Crash in MiFindExportedRoutineByName is really possible

Hi guys,

I saw that this question was already posted three or four times in both the NTFSD and NTDEV lists. Now I faced this problem too while loading my driver on Windows 2000 SP4. I went step by step thru disassembler code under WinDBG starting from MmGetSystemRoutineAddress() and now I got some clarity for this crash.

I tried to get an address of DbgPrintEx routine under Windows 2000 SP4. MiFindExportedRoutineByName() routine most likely uses bisection method while searching for the requested routine in export name tables. It successfully failed to find DbgPrintEx routine in the NTOSKRNL.EXE module, then it started to search it in the HAL.DLL export table. But when one of the indexes dropped to zero after division by 2, MiFindExportedRoutineByName() tried to decrement it and this index became 0xFFFFFFFF. Then this index value was used to get an address of the next export name string for further comparison. As a result - BSOD…

I quickly checked different Windows kernels and it seems that this nastiest bug was only fixed in the Vista kernel where this zero index case is specially processed.

Just for information, I put down my BSOD dump analysis.

KMODE_EXCEPTION_NOT_HANDLED (1e)
This is a very common bugcheck. Usually the exception address pinpoints
the driver/function that caused the problem. Always note this address
as well as the link date of the driver/image that contains this address.
Arguments:
Arg1: c0000005, The exception code that was not handled
Arg2: 804cf5a2, The address that the exception occurred at
Arg3: 00000000, Parameter 0 of the exception
Arg4: 00071700, Parameter 1 of the exception

Debugging Details:

EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - The instruction at “0x%08lx” referenced memory at “0x%08lx”. The memory could not be “%s”.

FAULTING_IP:
nt!MiFindExportedRoutineByName+54
804cf5a2 8b348a mov esi,dword ptr [edx+ecx*4]

EXCEPTION_PARAMETER1: 00000000

EXCEPTION_PARAMETER2: 00071700

READ_ADDRESS: 00071700

DEFAULT_BUCKET_ID: INTEL_CPU_MICROCODE_ZERO

BUGCHECK_STR: 0x1E

PROCESS_NAME: System

EXCEPTION_RECORD: eb81b69c – (.exr ffffffffeb81b69c)
ExceptionAddress: 804cf5a2 (nt!MiFindExportedRoutineByName+0x00000054)
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 00000000
Parameter[1]: 00071700
Attempt to read from address 00071700

CONTEXT: eb81b2f4 – (.cxr ffffffffeb81b2f4)
eax=e135fe28 ebx=80062000 ecx=1fffffff edx=80071704 esi=80069bc4 edi=3ffffffe
eip=804cf5a2 esp=eb81b764 ebp=eb81b784 iopl=0 nv up ei pl nz na pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010206
nt!MiFindExportedRoutineByName+0x54:
804cf5a2 8b348a mov esi,dword ptr [edx+ecx*4] ds:0023:00071700=???
Resetting default scope

LAST_CONTROL_TRANSFER: from 804cf4f7 to 804cf5a2

STACK_TEXT:
eb81b784 804cf4f7 e135fe28 e135fe28 81f6d4b8 nt!MiFindExportedRoutineByName+0x54
eb81b7c0 bfe92b40 00000001 00160014 bfe92938 nt!MmGetSystemRoutineAddress+0xb5
eb81b7d4 bfe91118 81f6d4b8 00000000 81f6d4c4 testdrv!TDrvInitializeXpDebugApi+0x60
eb81b808 8054b583 81f6d410 8007b070 8007d438 testdrv!DriverEntry+0x68
eb81b850 8054b0aa 81f6d410 8007b070 8007b110 nt!IopInitializeBuiltinDriver+0x279
eb81b8b4 80549c86 80087000 eb81b9fc 00000000 nt!IopInitializeBootDrivers+0x2d4
eb81ba54 80548b4c 80087000 00000000 00000000 nt!IoInitSystem+0x5ef
eb81bda8 80455a82 80087000 00000000 00000000 nt!Phase1Initialization+0x7e2
eb81bddc 8046b012 8054836a 80087000 00000000 nt!PspSystemThreadStartup+0x54
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16

I found that this bug in MmGetSystemRoutineAddress on Windows XP was fixed
in some service pack along the road and I would like to be able to detect
this to avoid trouble for the users. I also found that on Windows XP x64 it
just returns NULL in most cases which is not very useful either.

/Daniel

wrote in message news:xxxxx@ntfsd…
> Hi guys,
>
> I saw that this question was already posted three or four times in both
> the NTFSD and NTDEV lists. Now I faced this problem too while loading my
> driver on Windows 2000 SP4. I went step by step thru disassembler code
> under WinDBG starting from MmGetSystemRoutineAddress() and now I got some
> clarity for this crash.
>
> I tried to get an address of DbgPrintEx routine under Windows 2000 SP4.
> MiFindExportedRoutineByName() routine most likely uses bisection method
> while searching for the requested routine in export name tables. It
> successfully failed to find DbgPrintEx routine in the NTOSKRNL.EXE module,
> then it started to search it in the HAL.DLL export table. But when one of
> the indexes dropped to zero after division by 2,
> MiFindExportedRoutineByName() tried to decrement it and this index became
> 0xFFFFFFFF. Then this index value was used to get an address of the next
> export name string for further comparison. As a result - BSOD…
>
> I quickly checked different Windows kernels and it seems that this
> nastiest bug was only fixed in the Vista kernel where this zero index case
> is specially processed.
>
> Just for information, I put down my BSOD dump analysis.
>
> KMODE_EXCEPTION_NOT_HANDLED (1e)
> This is a very common bugcheck. Usually the exception address pinpoints
> the driver/function that caused the problem. Always note this address
> as well as the link date of the driver/image that contains this address.
> Arguments:
> Arg1: c0000005, The exception code that was not handled
> Arg2: 804cf5a2, The address that the exception occurred at
> Arg3: 00000000, Parameter 0 of the exception
> Arg4: 00071700, Parameter 1 of the exception
>
> Debugging Details:
> ------------------
>
> EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - The instruction at “0x%08lx”
> referenced memory at “0x%08lx”. The memory could not be “%s”.
>
> FAULTING_IP:
> nt!MiFindExportedRoutineByName+54
> 804cf5a2 8b348a mov esi,dword ptr [edx+ecx4]
>
> EXCEPTION_PARAMETER1: 00000000
>
> EXCEPTION_PARAMETER2: 00071700
>
> READ_ADDRESS: 00071700
>
> DEFAULT_BUCKET_ID: INTEL_CPU_MICROCODE_ZERO
>
> BUGCHECK_STR: 0x1E
>
> PROCESS_NAME: System
>
> EXCEPTION_RECORD: eb81b69c – (.exr ffffffffeb81b69c)
> ExceptionAddress: 804cf5a2 (nt!MiFindExportedRoutineByName+0x00000054)
> ExceptionCode: c0000005 (Access violation)
> ExceptionFlags: 00000000
> NumberParameters: 2
> Parameter[0]: 00000000
> Parameter[1]: 00071700
> Attempt to read from address 00071700
>
> CONTEXT: eb81b2f4 – (.cxr ffffffffeb81b2f4)
> eax=e135fe28 ebx=80062000 ecx=1fffffff edx=80071704 esi=80069bc4
> edi=3ffffffe
> eip=804cf5a2 esp=eb81b764 ebp=eb81b784 iopl=0 nv up ei pl nz na pe
> nc
> cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000
> efl=00010206
> nt!MiFindExportedRoutineByName+0x54:
> 804cf5a2 8b348a mov esi,dword ptr [edx+ecx
4]
> ds:0023:00071700=???
> Resetting default scope
>
> LAST_CONTROL_TRANSFER: from 804cf4f7 to 804cf5a2
>
> STACK_TEXT:
> eb81b784 804cf4f7 e135fe28 e135fe28 81f6d4b8
> nt!MiFindExportedRoutineByName+0x54
> eb81b7c0 bfe92b40 00000001 00160014 bfe92938
> nt!MmGetSystemRoutineAddress+0xb5
> eb81b7d4 bfe91118 81f6d4b8 00000000 81f6d4c4
> testdrv!TDrvInitializeXpDebugApi+0x60
> eb81b808 8054b583 81f6d410 8007b070 8007d438 testdrv!DriverEntry+0x68
> eb81b850 8054b0aa 81f6d410 8007b070 8007b110
> nt!IopInitializeBuiltinDriver+0x279
> eb81b8b4 80549c86 80087000 eb81b9fc 00000000
> nt!IopInitializeBootDrivers+0x2d4
> eb81ba54 80548b4c 80087000 00000000 00000000 nt!IoInitSystem+0x5ef
> eb81bda8 80455a82 80087000 00000000 00000000 nt!Phase1Initialization+0x7e2
> eb81bddc 8046b012 8054836a 80087000 00000000
> nt!PspSystemThreadStartup+0x54
> 00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16
>
>