Author Archives: Myria

Skype Reads Your BIOS and Motherboard Serial Number

Users of Skype that run 64-bit versions of Windows like me probably have noticed that when starting Skype, the following dialog box appears:

The program or feature “??C:Documents and SettingsMyriaLocal SettingsTemp121.com” cannot start or run due to incompatibility with 64-bit versions of Windows. Please contact the software vendor to ask if a 64-bit Windows compatible version is available.

Well, that’s weird. Skype’s trying to run a .com file, which won’t work on Win64 because there’s no NTVDM. Let’s try opening it in Hex Workshop. Access denied? OK, I’ll terminate Skype to read it. Still can’t?! This thing is really starting to annoy me. I’ll use WinDbg to terminate winlogon.exe to force a kernel panic. I reboot and NOW I can read the damn file.

An unreadable executable file coming from Skype sounds interesting, so I look at it. It’s 46 bytes long. For copyright reasons I can’t post the file or a complete disassembly. However, I can describe the program in terms of 16-bit DOS C:

int main(void)
{
fwrite((const void far*) 0xF0000000, 1, 0xFFFF, stdout);
fwrite((const void far*) 0xF000FFFF, 1, 1, stdout);
return 0;
}

It’s dumping your system BIOS, which usually includes your motherboard’s serial number, and pipes it to the Skype application. I have no idea what they’re using it for, or whether they send anything to their servers, but I bet whatever they’re doing is no good given their track record.

In 32-bit Windows NT, including Vista, the kernel permits NTVDM to make a read-only mapping of the BIOS at address 000F0000. This allows DOS programs running under NTVDM to make use of the BIOS. That’s how this 46-byte program is capable of sending the BIOS to the Skype application, and also explains why they use this mechanism to begin with.

If they hadn’t been ignorant of Win64′s lack of NTVDM, nobody would’ve noticed this happening.

Black Hat letdown

I went to Black Hat over Wednesday and Thursday. The presentation most people wanted to see (including me) was Joanna Rutkowska breaking the Vista x64 driver signing that I hate so much. I wanted to see what trick she’d found. I was let down, however, when she presented her technique.

Her trick was to allocate a bunch of memory so that the kernel pages itself and drivers out, uses raw disk access to overwrite the pagefile, then does an uncommon operation that causes her desired code to execute in kernel mode. Sound familiar? This is the same thing I proposed as a reason why x64 driver signing is pointless when I whined about the real reason for driver signing. I’d already thought of it, so it was nothing new to me, like most of the rest of the conference.

Obviously, Joanna thought of it long before I did, so there is nobody to blame for it. Except, I guess, Microsoft.

Win32's MulDiv

In Win32, there is an API call called “MulDiv”:

The MulDiv function multiplies two 32-bit values and then divides the 64-bit result by a third 32-bit value. The return value is rounded up or down to the nearest integer.

int WINAPI MulDiv(
int nNumber,
int nNumerator,
int nDenominator
);

If a divide overflow (including divide by zero) occurs, MulDiv returns -1. (Stupidly, there’s no way to actually check whether the result truly is -1 instead of an error.)

How do we implement this in x86-32? The official version does not use structured exception handling to simply catch the exception and handle it. MulDiv actually checks for overflow beforehand and never causes an exception.

The official implementation is several pages long, and I think we could do much better.

If this were the unsigned case, the entire function would be simple:

mov eax, [esp+4]
mul dword ptr [esp+8]
cmp edx, [esp+12]
jae overflow
div dword ptr [esp+12]
ret 12
overflow:
or eax, -1
ret 12

The C ! operator

In C, the ! (“logical NOT”) operator used on a value x evaluates to 0 when x is not 0, and 1 when x is 0. In other words, it’s equivalent to the following C:

(x == 0) ? 1 : 0

How should this be implemented in x86 assembly language, when “x” is already in a register? The target register can either be the same one, or it can be a different one. I didn’t try too hard and got 7 bytes; it can probably be made better. On other CPUs, it can be done in a single instruction. For example, in MIPS: “sltiu dest, src, 1″.

Note that this is about the case where the compiler doesn’t know how the result of the ! is used, as in “return !x;” in a non-inlined function. Cases like “if (!x)” are simpler.

(If you want to share how easily it can be done on *your* favorite CPU, please post a comment as well!)

The real reason for driver signing in Vista x64

In Windows Vista x64, drivers are required to be signed by someone holding a VeriSign code certificate or they won’t load. There is no way to (permanently) disable this signing even if you are Administrator. The F8 startup menu has an option to disable it, but you must select it every time you boot up. Microsoft’s claimed reason for this is that it prevents Trojans from installing kernel-mode rootkits. That is a load of crap. Continue reading

Microsoft changes CS value in Win64

I just found out the hard way that in 32 bit programs under Win64, the value of CS changed. In Win32, the value of CS is 0x001B. In 32 bit programs under Win64, it’s 0×0023. This will probably break some programs, especially debuggers.

Why did Microsoft do this? It’s not like the value of CS is undocumented: it’s in the DDK as KGDT_R3_CODE, and I’ve seen it several times in other places on MSDN. I can’t see any reason that they changed it. The 64 bit CS didn’t replace it – the 64 bit CS is 0×0033.

Normally I wouldn’t post 2 things in 2 days but this just really annoys me.

myria

Simple compiler optimization

I thought of an optimization that compilers for most CPUs could do that I think should be implemented. Let’s say you have C code like this:

if ((variable == 4) || (variable == 6)) { stuff }

Any existing compiler I know of would compile into something like this (eax is variable):

cmp eax, 4
jz label
cmp eax, 6
jz label

That’s a bad way to do it. It should be implemented more like this:

or eax, 2
cmp eax, 6
jz label

This saves one instruction, but more importantly, it saves a conditional branch. Conditional branches can be expensive on modern hardware. This will work on any similar “if” statement whose constants differ by a single bit.

Even if you must copy eax to another register first, it removes a conditional branch, which is probably a win. The situations in which to do this are more complicated and must take into account many things.

For constants that are 1 apart but not 1 bit apart, like 7 and 8, you can do:

sub eax, 7 // use dec eax in 1/2 case
test eax, 0xFFFFFFFE // this is a 3 byte opcode
jz label

This also works for 0 and -1: increment eax first.

myria

Puzzle: PowerPC Flag Simulation on x86

This week’s puzzle is to copy the carry flag to the high bit of ah.  You may destroy any other register, the flags, and the other 24 bits of eax.  Shortest sequence wins.

For an optional very long description of what this is all about, click “Read the rest”.  You don’t need to read it to participate in the contest =)

Continue reading

First assembly puzzle!

This is our first assembly language puzzle for the new site! These puzzles are tests to see whether you are good enough of an assembly nerd, and to learn some tricks if you’re not =^_^=

Our first puzzle is of a classic type: size optimization.  It is for x86-32 assembly language, certainly the most widely known assembly language.  We will definitely do other puzzles for other processors though!

You might find that many of these puzzles are good ideas to place into compilers and other automated assembly/machine code generators.

The puzzle: In terms of opcode bytes, find the smallest sequence of x86-32 instructions to implement the following C/C++ code:

if ((x == 0) || (y == 0))
    goto label;

Rules:

  • x and y are 32-bit integers or pointers.
  • x and y are each already in general-purpose registers or memory locations of your choice.
  • Do not assume a particular state of the flags, except that you may assume the direction flag is always clear as that is its usual state.
  • You may destroy any general-purpose registers or memory locations as you see fit, including the locations of x and y.
  • Assume that label is within range of a short jump.
  • Do not assume that you have access to protected instructions.
  • In general, answers that are the same size but faster or less destructive are considered better than others.

I was rather verbose in the rules because it’s the first puzzle.  Future puzzles won’t necessarily mention these restrictions.

Answers that don’t fit all the rules but have other merits like creativity are certainly welcomed!

The smallest answer I could find was 6 bytes.  The straightforward answer is 8 bytes.  Good luck!

-Myria

(check comments for solution(s))