Tuesday, October 30, 2012

Virtual PC vs. CPUID

In this post i will show another weird behavior of Virtual PC 2007. This time it is about the CPUID instruction. As most of you already know well what the CPUID is for and how it works, i will directly jump into the main topic.

In Virtual PC, executing CPUID disables interrupts for one instruction. Oh, wait, how is that?

Imagine we want to trace a sequence of x86 instruction. What the debugger does in that situation is as follows:
1) Calls the "GetThreadContext" function to extract the current context of the thread executing this sequence of instructions.
2) Modifies the "EFLAGS" register of the "CONTEXT" structure such that the Trap flag (TF) is set. EFLAGS is situated at offset 0xC0 from the start of the structure for the x86 version. TF is bit number 8 (0x100).
3) Calls the "SetThreadContext" and "ContinueDebugEvent" functions to continue execution.

When the trap flag is set, after executing an x86 instruction, an exception EXCEPTION_SINGLE_STEP is raised and trap flag is cleared.

The debugger receives the exception and resets the trap flag as shown above and so on.

Disable interrupts, what does that mean?
Executing certain instructions when the trap flag is set, no EXCEPTION_SINGLE_STEP exception is raised. The exception is raised after executing the instruction following them. One example instruction that disables interrupts is POP SS. POP SS has been used for a long time as an anti-tracing trick. Since it disables interrupts for one instruction, dumping the EFLAGS register to stack via . PUSHFD reveals the Trap Flag.


Executing CPUID in Virtual PC 2007, i found out that it has the same effect as POP SS. CPUID disables interrupts for one instruction.

I created a simple demo that exploits this bug to detect whether it is running inside Virtual PC 2007. It has been tested on Windows XP SP2 running inside Virtual PC 2007.

Reason for that is still under research but it seems to be due to the Virtualized CPUID (Intel FlexMigration) hardware support since the trick only works if Hardware Virtualization is enabled.

You can download the demo from here and its source code from here.

N.B. VirtualBox v4.1.22 r80657 is also affected by this bug.

N.B. Parallels Desktop is reportedly affected by this bug.

You can follow me on Twitter @waleedassar.

Monday, October 29, 2012

Virtual PC vs. DR7

In this post i will show you another weird behavior of Virtual PC 2007. This time the trick is about how Virtual PC handles the debug register DR7 known as Debug Control register.

For those who don't know, DR7 is used to specify the conditions under which the EXCEPTION_SINGLE_STEP exception is triggered for addresses held in DR0-DR3.
If we want to dissect DR7, it would be as follows:
Bit 0     ---> DR0 is locally enabled.
Bit 1     ---> DR0 is globally enabled.
Bit 2     ---> DR1 is locally enabled.
Bit 3     ---> DR1 is globally enabled.
Bit 4     ---> DR2 is locally enabled.
Bit 5     ---> DR2 is globally enabled.
Bit 6     ---> DR3 is locally enabled.
Bit 7     ---> DR3 is globally enabled.

Bit 8     ---> The "Local Enable Bit". Also for "Last Branch" tracing.
Bit 9     ---> The "Global Enable Bit". Also for "Last Branch" tracing.
Bit 10   ---> Reserved.
Bit 11  ----> Reserved.
Bit 12 -----> IR
Bit 13 -----> GD
Bit 14 -----> TB
Bit 15 -----> TT

Bit 16 -----
                  | ----> When DR0 is triggered.
Bit 17 -----
Bit 18 -----
                  | ----> Size of DR0's trigger condition.
Bit 19 -----
Bit 20 -----
                  | ----> When DR1 is triggered.
Bit 21 -----
Bit 22 -----
                  | ----> Size of DR1's trigger condition.
Bit 23 -----

Bit 24 -----
                  | ----> When DR2 is triggered.
Bit 25 -----
Bit 26 -----
                  | ----> Size of DR2's trigger condition.
Bit 27 -----
Bit 28 -----
                  | ----> When DR3 is triggered.
Bit 29 -----
Bit 30 -----
                  | ----> Size of DR3's trigger condition.
Bit 31 -----

For example:
Imagine we want to place a Hardware-Breakpoint-On-Execution for an instruction at 0x401000. See image below.

What the debugger does in this case is:
1) Sets DR0 to 0x401000.
2) Sets bit 0 of DR7 to 1.
3) Sets bit 8 of DR7 to 1 (for backward compatibility).
4) Sets bits 16 and 17 of DR7 to 00 (00 means On-Execution).

And if we then want to place a Hardware-Breakpoint-On-Write-Four for memory at 0x10000. See image below.
What the debugger does in this case is:
1) Sets DR1 to 0x10000.
2) Sets bit 2 of DR7 to 1.
3) Sets bit 8 of DR7 to 1 (for backward compatibility).
4) Sets bits  20 and 21 of DR7 to 01 (01 means On-Write).
5) Sets bits  22 and 23 of DR7 to 11 (11 for the size of trigger condition means to watch four bytes).

Now let's try to get back to the main topic of this post.

Hereafter, i will call the second byte of DR7 (byte 0xBB of 0xDDCCBBAA) the flags byte, just for brevity.

On Windows XP, if we set the flags byte to any value ranging from 0x00 to 0xFF, the breakpoint is always active and the exception is always raised whenever the trigger condition is met e.g. if we set DR7 to 0x0000FF01 (a hardware breakpoint On-Execution with Local enable, global enable, reserved, reserved, IR, GD, TB, and TT bits set), the exception is raised whenever the address in DR0 executes.
The same applies for Windows 7.

What about Virtual PC 2007? 

In Virtual PC 2007 with Windows XP installed inside, with certain flags set in DR7 e.g. 0x00003F01, the breakpoint is sometimes not activated.

So, i created simple executable that brute-forces the DR7's flag byte and based on the number of times the exception is raised it determines whether it is running inside Virtual PC 2007.

You can download the demo from here and its source code from here.
 
N.B. It has been tested with Windows XP SP2 and SP3.
N.B. VirtualBox is also affected, but i will leave this for a future post.


Any comments or ideas are very welcome. You can also follow me on Twitter @waleedassar

Saturday, October 27, 2012

Virtual PC vs. Resume Flag

In this post i will show you another weird behavior of Virtual PC 2007. I encountered this weird behavior while playing with Virtual PC 2007 with Windows XP SP3 installed inside. The behavior is all about how a Windows XP Virtual PC virtual machine handles the Resume Flag.

For those who don't know, the Resume Flag (Flag no. 16 in the EFLAGS register) is used to temporarily disable Hardware Breakpoints exceptions for one instruction. Without it, a Hardware-Breakpoint-On-Execution would infinitely trigger an EXCEPTION_SINGLE_STEP exception.

According to @osxreverser, Windows XP does not support the Resume Flag (RF). I was also amazed to see that also WinDbg and OllyDbg v1.10 don't use the resume flag. They use the Trap Flag (TF) instead.

Running a simple executable that on purpose makes use of the Resume Flag inside an XP Virtual PC Virtual Machine, i found out that execution flows normally as if XP supports the resume flag.

Given the finding above, i created a small executable that tries to detect if it is running inside Virtual PC 2007.
You can find it here and its source code from here.

I guess the finding above only applies if the host operating system itself supports the resume flag e.g. Windows 7 or later.

N.B. This topic is still under research.

Please don't hesitate to leave a comment.
You can also follow me on Twitter @waleedassar

Thursday, October 25, 2012

Virtual PC Machine Reset

While playing with Virtual PC 2007, i came up with an interesting trick not only to detect Virtual PC 2007 but also to reset (restart) the Virtual Machine.

The trick is so simple that all you need to do in your code is execute "\x0F\xC7\xC8\x05\x00"

Executing that x86 instruction sequence causes the following message to pop up.
A POC can be found here and its source from here.

N.B. Other x86 instruction sequences can cause the same result.

Any comments or ideas are welcome.
You can follow me on Twitter @waleedassar