Pointer Stew

A friend of a friend ran across this little gem the other day. See what you can make of it:

char *c[]={
        "ENTER",
        "NEW",
        "POINT",
        "FIRST"
};
char **cp[]={c+3,c+2,c+1,c};
char ***cpp=cp;
main()
{
        printf("%s",**++cpp);
        printf("%s ",*--*++cpp+3);
        printf("%s",*cpp[-2]+3);
        printf("%s\n",cpp[-1][-1]+1);
}

Nar Ganapathy on Channel9

I’m spending the day catching up on the world around me, and I ran across a video of Nar Ganapathy, one of the I/O Manager architects, discussing things like the user mode driver framework and other related issues.

Launch Video

DevCon Wrap-up

Wow, what a week! I’m still recovering. There were some amazingly cool presentations and tons of technical details that I’d be hard-pressed to locate anywhere else. Not quite as intensely cool as the previous DevCon – they really need to move it back to the campus – but still totally worthwhile.

I wound up spending much of my time on general driver development issues, outside of a few NDIS6-related sessions. Unfortunately, as it was an NDA event, I have to research any DevCon-related posts pretty carefully to make sure everything was public.

All in all, I’d definitely go back again next year.

DevCon Day 2

Well, it’s been another interesting day at DDC 2005. I’ve been in 3 NDIS-related presentations, a PCI Express presentation, a driver hang presentation, and a build environment discussion. Lots of fun all around, although I was disappointed to see how much I had forgotten about the cancel race since I wrote my series of CSQ articles earlier.

Off to an Intel-sponsored event this evening. Sounds like a hoot – Gibson guitars being given away – what more could you want?

Q & A

Day 2 of DevCon has started out looking promising as usual. We were treated this morning to an interesting NDIS6 refresher by the NDIS tech lead. The amazingly great thing about DevCon is exactly this – the guys and gals that write the code and define the APIs are there to describe them. It’s under NDA, so the amount of dancing around is kept to a minimum (unless, of course, I have something like So Says I by The Shins in my head). Today looks like it’s mainly an NDIS day for me. Can a conference be any more exciting?!?!

I did want to respond in general to thos that occasionally drop me direct questions. I will try to answer as I have some free time and feel motivated, and particularly so if it would make a good general article, but you really shouldn’t depend on that, particularly given the infrequency of my blog updates lately. 🙂 I’d really recommend jumping on the NTDEV and NTFSD lists over at www.osronline.com.

Hot Patching

Well, how frustrating is this… as far as I can tell, .Text completely ate my last post, except for a couple of sentences at the top. I’ve switched to writing these posts off-line (like a real blogger!), so hopefully that’s the last time this will happen to me.

Some co-workers and I were discussing a change you may have noticed in recent
Windows kernel binaries. Disassembling into a kernel function shows an
odd-looking instruction at the top:

   lkd> u NtCreateFile
   nt!NtCreateFile:
   80570d48 8bff             mov     edi,edi
   80570d4a 55               push    ebp
   80570d4b 8bec             mov     ebp,esp
   ...

Notice the ‘mov edi,edi’ at the top – that would seem to be a creative no-op,
and in fact, it is. This seemingly useless instruction is designed to enable a
new capability for modern kernels: hot patching. Hot patching is designed to
address the availablility requirements of modern servers (and workstations, for
that matter), by enabling certain hotfixes to patch the live kernel and redirect
function calls from the existing function into a replacement (or
potentially a filter function, etc). Administrators need something like this to
enable them to apply hotfixes in a timely manner, rather than having to wait for
a maintenance window. The world is a better place when servers are patched!

Technically, this works by replacing those two extra MOV bytes at the top of a
function with a jump instruction. Now, some of you may have noticed that, on
x86, two bytes will only get you a short jump, good for 127 bytes in either
direction. Clearly this isn’t going to do it – you’d have to write the new
function into memory that is probably occupied by another function, which is no
good. However, a little extra searching reveals this:

   lkd> u NtCreateFile-0x10
   nt!NtOpenFile+0x55:
   80570d38 0f841afdffff     je      nt!FsRtlCurrentBatchOplock+0xf7 (80570a58)
   80570d3e e9cd440600       jmp    nt!FsRtlRegisterUncProvider+0x18b (805d5210)
   80570d43 90               nop
   80570d44 90               nop
   80570d45 90               nop
   80570d46 90               nop
   80570d47 90               nop
   nt!NtCreateFile:
   80570d48 8bff             mov     edi,edi
   ...

Well, just what we needed – five extra bytes in which to place a long jump (relative
to the current selector). Those five bytes can get patched on-the-fly with the pointer
to the real function. Because they’re immediately before the MOV, they’re in range for our short jump.
The hotfix can then write a relative long jump into those NOP bytes that points to the replacement function.

This design is interestng for several reasons. First, Microsoft chose to use the
“creative no-op”, rather than two real NOP instructions, even though they then
used five real NOPs for the long jump. The reason is easy – the MOV is called every
time the function is called, whether it is hooked or not (or, more precisely, when it
its not hooked). Because you could be talking about a measurable performance impact on high-traffic code paths,
those two bytes should get executed as fast as possible, and
with minimal side-effects. The mov is just what the doctor ordered – as a single instruction,
it should execute faster than two consecutive NOP instructions.

Why didn’t Microsoft just put the five NOPs in as the first bytes of the
function (rather than using the short jump)? Again, the question is performance
– they have optimized for the common case (the unhooked function), rather than
the uncommon case. This costs two extra bytes per function statically, but they
save you 2/3 of the instructions (assuming you reserved your five bytes with
MOV / MOV / NOP).

One other question that came up was why Microsoft didn’t just use Detours, or
something much like it. Detours relies on disassembly to perform runtime hooks
like these, and it winds up overwriting a number of bytes at the begining of the
function to make this work. This is difficult, at best – the implemented solution
is much more robust. The cost is an extra seven bytes per function, but
it’s worth it, IMO.

This is an interesting, and instructive, bit of low-level software engineering, where
space, performance, and robustness must be balanced.

The Browser Ate My Homework

I just finished a post and found that only the first paragraph was posted. .Text seems to have eaten the rest of it. My apologies – I’ll re-post later on.

DDK MVP Dinner

I just spent an immensely interesting evening with a group of DDK MVPs and Microsoft folks – good wine, great food, and great conversation. I’m reminded again that in general, Microsoft manages to attract smart and interesting people to build its products.


Not playing anything at the moment, but The Shins’ Chutes Too Narrow has been running through my head all day, much to the annoyance of my travelling companions.

DevCon

DevCon is finally here. I’ve been waiting for 18 months or so since the last one – it was really a blast then, and the schedule looks just as interesting this time. Here’s hoping! I almost wound up here a week early, though – I actually bought plane tickets for myself and two of my co-workers for last week, and it wasn’t until I sent the itenerary out at the office that they corrected me. Fortunately, I had waited so long to buy tickets that my only option was refundable, so it all worked out okay. 🙂

I have been hinted at by those same co-workers that /YX doesn’t actually work very well for them. I am too lazy to reproduce the brokenness that they report, but seemingly it is not the bowl of cherries that I thought it was.

Anyway, Seattle is much nicer than Kansas City today, and I’m looking forward to the coming week’s worth of seminars.