OSRLogo
OSRLogoOSRLogoOSRLogo x Subscribe to The NT Insider
OSRLogo
x

Everything Windows Driver Development

x
x
x
GoToHomePage xLoginx
 
 

    Thu, 14 Mar 2019     118020 members

   Login
   Join


 
 
Contents
  Online Dump Analyzer
OSR Dev Blog
The NT Insider
The Basics
File Systems
Downloads
ListServer / Forum
  Express Links
  · The NT Insider Digital Edition - May-June 2016 Now Available!
  · Windows 8.1 Update: VS Express Now Supported
  · HCK Client install on Windows N versions
  · There's a WDFSTRING?
  · When CAN You Call WdfIoQueueP...ously

MmGetSystemRoutineAddress IS BROKEN!?

Updated 5 June 2007:

It seems that I missed a story recently.  M'ijo Peter was reading NTDEV recently, when driver expert Bill McKenzie asked a simple question:

Am I crazy, or is MmGetSystemRoutineAddress supposed to return NULL when it does not find the requested system routine name...? On XP SP2, looking for CmRegisterCallbackEx using MmGetSystemRoutineAddress it blue screens everytime.

Bill even posted a nice, simple, example and a detailed crash dump.

I know, I know... you're thinking "How can there be a bug in so fundamental a DDI as this, and not have more people know about it?"  Well, as the members of NTDEV pointed out, it seems that this has been a well-known problem for quite a while.  Konstatin Manurin posted an analysis of the problem back in November of 2006 (see http://www.osronline.com/showThread.cfm?link=101536).

The boys up in Redmond (thank you DoronH and RobertKj) have confirmed that this is a indeed a known problem that's fixed in Vista and slated for fix in XP SP3.

OSR's PeterGV has indicated that it's also fixed in S03 SP1.

Contrary to initial guidance, MS sources have indicated that it is not safe to catch this error in a try/except block.  Apparently, catching the error with SEH can result in a lock not being properly released.  Ugh.

The latest guidance is to build-knowledge into your code as to whether the function you want to call is exported, so to check for  CmRegisterCallbackEx which was first provided on Vista, your code would look something like:

if ( RtlIsNtDdiVersionAvailable(NTDDI_LONGHORN) ) {

    //
    // This function is available...
    //
    rtnToCall =  MmGetSystemRoutineAddress (...);

} else {

    //
    // The function's not available... get a pointer to an alternative function
    //
    rtnToCall =  MmGetSystemRoutineAddress (...);

}

This technique complicated by the fact that the WDK docs don't typically say when a DDI was first implemented.

Also, given that the bug is fixed on Vista and Server 2003 SP1 and later system, you can use RtlIsNtDdiVersionAvailable and RtlIsServicePackVersionInstalled to check to see if it's safe to call MmGetSystemRoutineAddress.

A mess for all, that's for sure.

Another possible work-around (and the one we've chosen to use here at OSR) is to write your own version of MmGetSystemRoutineAddress.  Believe it or not, you can even do it with documented DDIs...  Check out the AuxKlibQueryModuleInformation (which is implemented in a static library that's only present in the Vista build environment of the WDK).

User Comments
Rate this article and give us feedback. Do you find anything missing? Share your opinion with the community!
Post Your Comment

Post Your Comments.
Print this article.
Email this article.
bottom nav links