Visual C++ Defenses and 64-bit

Michael Howard just published a good article here on how Visual C++ features can help protect your app. I go into a fair bit more detail on these in our most recent book, "Writing Secure Code for Windows Vista" (WSCV) if you're curious. Something Michael left out of the article was how this changes when you go to 64-bit – to be completely accurate, I'd need to go sit down with my compiler and debugger and go look at the actual code that's emitted – which I don't have time for this evening – but I'll take a shot anyway, and if I get something wrong, I'm sure someone will correct me.

  • Stack Overrun detection – by and large the same stuff as on x86, but with one interesting twist. There's a lot more registers available in x64, which is part of why some code runs faster on x64, and one of the things that changes is that x64 uses fastcall as the default calling convention. What this does on x86 is that it puts the first argument into a register rather than pushing it on the stack. If it's in a register, it can't be overrun as easily. On x64, it puts the first four arguments in registers. So this largely removes a fairly significant attack vector, and means that most functions won't need duplicate arguments in 2 places on the stack. It's also arguably a little safer, since a buffer _underrun_ might still get the x86 code, but won't typically attack the argument on x64.
  • SafeSEH – IIRC, the exception handlers get compiled in, and aren't loitering on the stack to see if they'll get mugged.
  • NXCompat – everyone gets this, like it or not. Much safer that way.
  • DynamicBase (ASLR) – I don't think there's any changes here.

The CRT is still the CRT, so no difference there, and new is the same thing as before. Something else that we do that I learned from John McDonald is that when you call delete[], the destructor needs to get called for every object in the array. Some other compilers will run through the whole array, calling the destructor for each object in turn, referencing what that object claims is its destructor. Thus if someone can whack a vtable for just one of them, off to the arbitrary code races we go. Visual C++ will just call the destructor function for the first one, and it's less likely that an attacker can get to that one vtable – this ends up being safer.