June 13th, 2022

Adventures in application compatibility: The case of the PC-relative indirect jump that reads from nowhere

A spike of Explorer crashes occurred with the release of a particular Windows Insider build. The crash looked like this:

00007ffb`25cc0000 ff25b29e0600    jmp     qword ptr [00007ffb`25d29eb8] ds:00007ffb`25d29eb8=????????????????

The code did not correspond to any loaded DLL, so this is the result of some sort of code injection. The return address on the stack provided a clue:

00007ffb`25cc0000
explorer!TrayUI::RefreshPixieDust+0xab
explorer!TrayUI::WndProc+0x1086
.. window message dispatch functions ..

This particular code path runs when you change themes, which isn’t something you do frequently, but even in the a Windows Insider population, it happens often enough that the crashes show up as significant in Windows Error Reporting. The TrayUI::RefreshPixieDust method crashed at the call to user32!Set­Window­Pixue­Dust:

00000001`4004345c 48ff1555c92700  call    qword ptr [explorer!_imp_SetWindowPixieDust (00000001`402bfdb8)]
00000001`40043463 0f1f440000      nop     dword ptr [rax+rax]

A look at the Set­Window­Pixie­Dust function shows that it has been detoured!

// normal:
00007ffb`25217560 ff25b29e0600    jmp     qword ptr [user32!_imp_NtUserSetWindowPixieDust (00007ffb`25281418)]

// crash dump:
00007ffb`25217560 48b80000cb25fb7f0000 mov rax, 7ffb25cb0000
00007ffb`2521756a ffe0            jmp     rax

At this point, I did some analysis of the crash dumps to see if there was something common to all of the crashes. And I found one: In every crash, a popular third-party “shell enhancement” was running.

So now we know who is doing the detouring. They’re probably doing it so that they can “add extra features” to Explorer.

Reminder: Detouring the operating system is not supported. This program is doing unsupported things, but their customers don’t know or care.

Let’s take a close look at the crashing instruction:

00007ffb`25cc0000 ff25b29e0600    jmp     qword ptr [00007ffb`25d29eb8] ds:00007ffb`25d29eb8=????????????????

Notice that the code bytes are identical to the original instruction: ff 25 b2 9e 06 00.

The problem is that the instruction they are trying to replicate uses RIP-relative addressing, and they didn’t take that into account. The disassembler is doing you a favor and converting the RIP-relative address to an absolute address. A more literal disassembly would be

00007ffb`25217560 ff25b29e0600    jmp     qword ptr [rip+69eb2h]

With this rewrite, it becomes more obvious that just copying this instruction to another location will alter its behavior, since the relocated instruction will have a different rip.

I added to the email thread one of my colleagues who used to work at the company that wrote the software in question, hoping that they might still have contacts at their old company to help get this fixed. My colleague wrote back, “The sad thing here is I wrote the detour code, or at least the 32-bit version of the detour. It looks like they missed a spot when they added 64-bit support.”

Anyway, the company issued a fix for their detour code, and the crashes eventually stopped.

Topics
Code

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

10 comments

Discussion is closed. Login to edit/delete existing comments.

  • Yuhong Bao

    Do you know why they needed to detour?

  • Paul Jackson

    > They’re probably doing it so that they can “add extra features” to Explorer.

    Is it a bad thing that people want or need extra features? If Microsoft would provide some APIs, maybe there won’t be a need in detours.

    • Antonio Rodríguez

      Of course, it's not a bad thing to have extra features. In fact, Explorer do have an official API for that, in the form of shell extensions, which register through known COM interfaces. But every extension API has to be limited in some way (what is not supported by the API is, by definition, not supported). Try to write a program that does something complex and provide ways to change its behavior in *every* way....

      Read more
      • Paul Jackson

        My point is that, in my opinion, the official APIs don’t cover enough use cases. Of course, covering every use case is not feasible, but Microsoft doesn’t cover even the common cases. Do you have APIs to customize the start menu? The taskbar? The explorer ribbon? Barely. And it’s becoming less customizable with time, both for users and for third party software.

      • Antonio Rodríguez

        Raymond has covered several times the reasons why that level of customization is not covered by the API. For starters, it would open them to be a war zone between competing applications. Would you like that when you open Google Chrome it removes all icons to Firefox or Edge, or place itself in an unmovable panel at the top of the Start Menu? Furthermore, if they did provide a full API to customize (for example)...

        Read more
      • Emily Bowman

        It’s worth noting the difference between Detours™ the Microsoft-published library, and “detouring” the microspeak for the general concept — whether that came from the product name or came before and influenced the product name, I wouldn’t know, but I do know it’s very commonly used (especially in .Net) for what other ecosystems generally call “hotpatching” by any means, not just that one library.

      • Ron ParkerMicrosoft employee · Edited

        While that's true, a lot of ISVs created their own version, because the licensing for Detours was cost-prohibitive for a lot of smaller companies back in the day. That may have changed, but in a lot of cases the die is already cast.

        The last project I did for my previous employer, as recently as five years ago, was to create a general-purpose library for various sorts of function/method hooks, including this kind. It wouldn't have...

        Read more
  • word merchant

    Just disallow detouring. Microsoft is big enough and rich enough to get away with ruining a few anti-virus and shell extensions (both examples of where the cure is way worse the the disease).

    Be honest: any company that promoted Teams on during a pandemic when we couldn’t avoid it clearly has little executive shame.

    • Ron ParkerMicrosoft employee

      I don’t believe that there’s any reasonable way to prevent detouring without also preventing fundamental things like JIT compilation. I’d be happy to be proven wrong, of course, even though in my previous life I have caused well more than my fair share of detours.