Anti-Debugging and Anti-VM using timing

I recently came across a Keygen-Me challenge that turned out to be surprisingly well protected with a simple timing technique. I thought at first it was simply designed to defeat step-by-step debugging. But it was capable of defeating several QEMU based virtual machine based tracing tools and Intel's PIN tracing tool. Let's have a look.

An rdtsc instruction, some more code, another rdtsc instruction and a check. The rdtsc instruction gives access to the processor's Time Stamp Counter:

So depending on whether the time counter on the virtual machine is virtualized or passed through, it can be detected.

Standard qira, when executing this program, causes it to careen off into a crash...

$ qira ./theexecutable
****** starting WEB SERVER on 0.0.0.0:3002
*** using base 0 for 0
on 0 going from 1 to 379490...*** WARNING, changing segment 0x8048000 134520300
done 163.008000 ms
on 0 going from 379490 to 697964...done 156.404000 ms
on 0 going from 697964 to 1026219...done 169.573000 ms
on 0 going from 1026219 to 1399111...done 194.284000 ms
on 0 going from 1399111 to 1831883...done 237.863000 ms
on 0 going from 1831883 to 2338968...done 293.269000 ms
on 0 going from 2338968 to 2953999...done 378.872000 ms
on 0 going from 2953999 to 3599337...qemu: uncaught target signal 11 (Segmentation fault) - core dumped
done 477.153000 ms
on 0 going from 3599337 to 3742593...done 91.464000 ms

Even instrumentation such as Intel PIN can be detected, if they slow down the code too much.

$ qira --pin ./theexecutable

A: qirapin.cpp: ThreadFini: 925: qirapin scratch register ended up with a weird value.
################################################################################
## STACK TRACE
################################################################################
??? at qirapin.so+0x2f452 

??? at qirapin.so+0x19bbf 

??? at qirapin.so+0x93a65 

??? at /home/ubuntu/Documents/qiraold/tracers/pin/pin-3.7-97619-g0d0c92f4f-gcc-linux/ia32/bin/pinbin+0x28ac82 

_ZN8LEVEL_VM19VM_SHUTDOWN_MANAGER16CompleteShutdownEPNS_9VM_THREADENS_16TERMINATE_REASONEj+0x61 at /home/ubuntu/Documents/qiraold/tracers/pin/pin-3.7-97619-g0d0c92f4f-gcc-linux/ia32/bin/pinbin+0x26e131 

_ZN8LEVEL_VM19VM_SHUTDOWN_MANAGER10DoShutdownEPNS_9VM_THREADENS_16TERMINATE_REASONEj+0x2dd at /home/ubuntu/Documents/qiraold/tracers/pin/pin-3.7-97619-g0d0c92f4f-gcc-linux/ia32/bin/pinbin+0x2716ad 

_ZN8LEVEL_VM11VM_ShutdownEPNS_9VM_THREADENS_16TERMINATE_REASONEj+0xa4 at /home/ubuntu/Documents/qiraold/tracers/pin/pin-3.7-97619-g0d0c92f4f-gcc-linux/ia32/bin/pinbin+0x271b24 

_ZN8LEVEL_VM12SIGNALS_IMPL18DeliverFatalSignalEjiPKNS_7CONTEXTEb+0x94 at /home/ubuntu/Documents/qiraold/tracers/pin/pin-3.7-97619-g0d0c92f4f-gcc-linux/ia32/bin/pinbin+0x2fd7e4 

_ZN8LEVEL_VM12SIGNALS_IMPL12FilterSignalEPNS0_15PER_THREAD_DATAEjPNS_8EMULATORERKN5PINVM7VSIGNALEPKN10LEVEL_BASE14EXCEPTION_INFOEPSt4listIS6_SaIS6_EEb+0x777 at /home/ubuntu/Documents/qiraold/tracers/pin/pin-3.7-97619-g0d0c92f4f-gcc-linux/ia32/bin/pinbin+0x3011a7 

_ZN8LEVEL_VM12SIGNALS_IMPL30CapturePendingSignalsAndFilterEPNS0_15PER_THREAD_DATAEjPNS_8EMULATOREPKN5PINVM7VSIGNALEPKN10LEVEL_BASE14EXCEPTION_INFOEPSt4listIS6_SaIS6_EEb+0x536 at /home/ubuntu/Documents/qiraold/tracers/pin/pin-3.7-97619-g0d0c92f4f-gcc-linux/ia32/bin/pinbin+0x301ad6 

_ZN8LEVEL_VM12SIGNALS_IMPL20HandlePendingSignalsEPNS0_15PER_THREAD_DATAEjPNS_8EMULATOREPKN5PINVM7VSIGNALEPKN10LEVEL_BASE14EXCEPTION_INFOEb+0x8f at /home/ubuntu/Documents/qiraold/tracers/pin/pin-3.7-97619-g0d0c92f4f-gcc-linux/ia32/bin/pinbin+0x30833f 

_ZN8LEVEL_VM12SIGNALS_IMPL19InternalHandlerSyncEiP7siginfoPN5PINVM11ISIGCONTEXTEPPKNS_14SCT_ATTRIBUTESEPNS_5PCTXTEPj+0x582 at /home/ubuntu/Documents/qiraold/tracers/pin/pin-3.7-97619-g0d0c92f4f-gcc-linux/ia32/bin/pinbin+0x30a592 

_ZN8LEVEL_VM12SIGNALS_IMPL20HandlePhysicalSignalEP7siginfoPN5PINVM11ISIGCONTEXTE+0x22e at /home/ubuntu/Documents/qiraold/tracers/pin/pin-3.7-97619-g0d0c92f4f-gcc-linux/ia32/bin/pinbin+0x30af2e 

_ZN5PINVM25SIGNAL_DETAILS_LINUX_IA3215InternalHandlerEiPvS1_+0x6d at /home/ubuntu/Documents/qiraold/tracers/pin/pin-3.7-97619-g0d0c92f4f-gcc-linux/ia32/bin/pinbin+0x39c87d 

Pin: pin-3.7-97619-0d0c92f4f
Copyright (c) 2003-2018, Intel Corporation. All rights reserved.

Pin app terminated abnormally due to signal 6.

Sure enough, it was the timing test that caused the crash:

Lets try the rr Record and Replay Framework by Mozilla:

https://github.com/mozilla/rr

$ rr record ./theexecutable
rr: Saving execution to trace directory `/home/jan/.local/share/rr/KeygenMe-0'.
Segmentation fault

It is vulnerable to this protection as well. gdbgui supports stepping forward and backwards through the trace.

$ gdbgui --rr

then inside of gdb we can execute up to the crash and step back a few instructions.

And sure enough, it's the timing test again...

The tools work fine after patching out the timing test.

The exectuable had more protections, and it was a great example of how useful qira is when it works.

Here is the writeup on that.