which tables ? it takes IMAGE_EXPORT_DIRECTORY no of names
and then does the shift
and in some point it crosses the threshhold 0 goes below the 0 and
crashes in the third iteration in xp-sp1 this no is
<hal.numberofnames> 0000005C
(((5b>1)>1)>1) and so on results in a nice bsod KMODE_EXCEPTION_NOT_HANDLED
i dont know if this list will reject this post or not
im posting an annoted disassembly of nt!MiFindExportedRoutineByName
00535324 >PUSH EBP
00535325 MOV EBP, ESP
00535327 SUB ESP, 14
0053532A LEA EAX, DWORD PTR SS:[EBP-14]
0053532D PUSH EAX ; /Arg4 = 0007E030
0053532E PUSH 0 ; |Arg3 = 00000000
00535330 PUSH 1 ; |Arg2 = 00000001
00535332 PUSH DWORD PTR SS:[EBP+8] ; |Mz header of hal
or ntoskrnl.exe
00535335 CALL NTOSKRNL.RtlImageDirectoryEntryT>;
\RtlImageDirectoryEntryToData
0053533A TEST EAX, EAX ; 00289B00
<hal.characteristics> 00000000
0053533C MOV DWORD PTR SS:[EBP-10], EAX
0053533F JE NTOSKRNL.005353D8
00535345 MOV EDX, DWORD PTR DS:[EAX+20] ; 00289B20
<hal.addressofnames>00019C98
00535348 MOV ECX, DWORD PTR DS:[EAX+24] ; 00289B24
<hal.addressofnameordinals> 00019E08
0053534B ADD ECX, DWORD PTR SS:[EBP+8] ;
0053534E ADD EDX, DWORD PTR SS:[EBP+8] ;
00535351 AND DWORD PTR SS:[EBP-4], 0
00535355 PUSH EBX
00535356 PUSH ESI ;
00535357 PUSH EDI
00535358 MOV EDI, DWORD PTR DS:[EAX+18] ; 00289B18
<hal.numberofnames> 0000005C
0053535B MOV EAX, DWORD PTR SS:[EBP+C]
0053535E MOV EAX, DWORD PTR DS:[EAX+4]
00535361 MOV DWORD PTR SS:[EBP-C], ECX
00535364 DEC EDI ; 5b
00535365 MOV DWORD PTR SS:[EBP-8], EAX
00535368 /MOV EAX, DWORD PTR SS:[EBP-4]
0053536B |LEA ECX, DWORD PTR DS:[EAX+EDI]
0053536E |MOV EAX, DWORD PTR SS:[EBP-8]
00535371 |SHR ECX, 1 ;
2d,16,0a,04,01,00,7fffffff,3fffffff,1fffffff
00535373 |MOV ESI, DWORD PTR DS:[EDX+ECX4]
00535376 |ADD ESI, DWORD PTR SS:[EBP+8] ;
00535379 |MOV DWORD PTR SS:[EBP+C], EAX
0053537C |/MOV EAX, DWORD PTR SS:[EBP+C]
0053537F ||MOV BL, BYTE PTR DS:[EAX]
00535381 ||MOV AL, BL
00535383 ||CMP BL, BYTE PTR DS:[ESI]
00535385 ||JNZ SHORT NTOSKRNL.005353A6
00535387 ||TEST AL, AL
00535389 ||JE SHORT NTOSKRNL.005353A2
0053538B ||MOV EAX, DWORD PTR SS:[EBP+C]
0053538E ||MOV BL, BYTE PTR DS:[EAX+1]
00535391 ||MOV AL, BL
00535393 ||CMP BL, BYTE PTR DS:[ESI+1]
00535396 ||JNZ SHORT NTOSKRNL.005353A6
00535398 ||ADD DWORD PTR SS:[EBP+C], 2
0053539C ||INC ESI ;
0053539D ||INC ESI ;
0053539E ||TEST AL, AL
005353A0 |\JNZ SHORT NTOSKRNL.0053537C
005353A2 |XOR EAX, EAX
005353A4 |JMP SHORT NTOSKRNL.005353AB
005353A6 |SBB EAX, EAX
005353A8 |SBB EAX, -1
005353AB |TEST EAX, EAX
005353AD |JGE SHORT NTOSKRNL.005353B4
005353AF |LEA EDI, DWORD PTR DS:[ECX-1] ; here it become
-1 when shr ecx above became 0
005353B2 |JMP SHORT NTOSKRNL.005353BC
005353B4 |JLE SHORT NTOSKRNL.005353C1
005353B6 |LEA EAX, DWORD PTR DS:[ECX+1]
005353B9 |MOV DWORD PTR SS:[EBP-4], EAX
005353BC |CMP EDI, DWORD PTR SS:[EBP-4]
005353BF \JNB SHORT NTOSKRNL.00535368
005353C1 CMP EDI, DWORD PTR SS:[EBP-4]
005353C4 POP EDI
005353C5 POP ESI ;
005353C6 POP EBX
005353C7 JL SHORT NTOSKRNL.005353D8
005353C9 MOV EAX, DWORD PTR SS:[EBP-C] ; HAL.00289E08
005353CC MOVZX EAX, WORD PTR DS:[EAX+ECX2]
005353D0 MOV ECX, DWORD PTR SS:[EBP-10] ; <hal.characteristics>
005353D3 CMP EAX, DWORD PTR DS:[ECX+14]
005353D6 JB SHORT NTOSKRNL.005353DC
005353D8 XOR EAX, EAX
005353DA JMP SHORT NTOSKRNL.005353EA
005353DC MOV ECX, DWORD PTR DS:[ECX+1C]
005353DF LEA EAX, DWORD PTR DS:[ECX+EAX4]
005353E2 MOV ECX, DWORD PTR SS:[EBP+8] ; HAL.00270000
005353E5 MOV EAX, DWORD PTR DS:[EAX+ECX]
005353E8 ADD EAX, ECX
005353EA LEAVE
005353EB RETN 8
On 6/2/07, Daniel Terhell wrote:
> BTW there must be also a bug in Windows Mail. Everytime it tells me ‘could
> not send post’. Then I send it again and it appears two posts have arrived.
> I am on 56K dialup so this doesn’t help but apologies for my double posts.
>
> /Daniel
>
>
>
> “Daniel Terhell” wrote in message
> news:xxxxx@ntdev…
> > Yes, in the case a name is not present then after an iteration of low=0
> > high =1, Mid becomes 0. Then High = Mid -1 wraps to 0x7FFFFFFF and the
> > loop still goes on with bogus values.
> >
> > ecx=00000000
> > ecx=7fffffff
> > ecx=3fffffff
> > ecx=1fffffff
> >
> > These values confirm my speculation this function uses unsigned types for
> > high, mid and low because if high would be -1 then the condition
> > while (high >= low) would no longer be valid and the loop would be
> > terminated.
> >
> > Maybe there is another problem with the tables. What are they supposed to
> > be filled with, exported function names only ?
> >
> > /Daniel
> >
> >
> > “raj_r” wrote in message news:xxxxx@ntdev…
> >> some where in the sequence ecx becomes 0 and then the next iterartion
> >> goes haywire
> >>
> >> this snippet is from w2k sp4
> >>
> >> and iirc the api (sorry i think the term is DDI ) on this sequence was
> >> NtDeviceIoControlFile
> >>
> >> Breakpoint 1 hit
> >> eax=e1291208 ebx=80062000 ecx=00000000 edx=8006e344 esi=8006e5ac
> >> edi=00000001
> >> eip=804ef7c7 esp=fb674ae4 ebp=fb674b04 iopl=0 nv up ei pl zr na
> >> pe
> >> cy
> >> cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000
> >> efl=00000247
> >> nt!MiFindExportedRoutineByName+0x54:
> >> 804ef7c7 8b348a mov esi,dword ptr [edx+ecx4]
> >> ds:0023:8006e344=0000c586
> >> kd>
> >> Breakpoint 1 hit
> >> eax=e1291208 ebx=80062000 ecx=7fffffff edx=8006e344 esi=8006e586
> >> edi=ffffffff
> >> eip=804ef7c7 esp=fb674ae4 ebp=fb674b04 iopl=0 ov up ei pl nz na
> >> pe
> >> cy
> >> cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000
> >> efl=00000a07
> >> nt!MiFindExportedRoutineByName+0x54:
> >> 804ef7c7 8b348a mov esi,dword ptr [edx+ecx4]
> >> ds:0023:8006e340=00005aa0
> >> kd>
> >> Breakpoint 1 hit
> >> eax=e1291208 ebx=80062000 ecx=3fffffff edx=8006e344 esi=80067aa0
> >> edi=7ffffffe
> >> eip=804ef7c7 esp=fb674ae4 ebp=fb674b04 iopl=0 nv up ei pl nz na
> >> pe
> >> nc
> >> cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000
> >> efl=00000206
> >> nt!MiFindExportedRoutineByName+0x54:
> >> 804ef7c7 8b348a mov esi,dword ptr [edx+ecx4]
> >> ds:0023:8006e340=00005aa0
> >> kd>
> >> Breakpoint 1 hit
> >> eax=e1291208 ebx=80062000 ecx=1fffffff edx=8006e344 esi=80067aa0
> >> edi=3ffffffe
> >> eip=804ef7c7 esp=fb674ae4 ebp=fb674b04 iopl=0 nv up ei pl nz na
> >> pe
> >> nc
> >> cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000
> >> efl=00000206
> >> nt!MiFindExportedRoutineByName+0x54:
> >> 804ef7c7 8b348a mov esi,dword ptr [edx+ecx4]
> >> ds:0023:0006e340=???
> >> kd> t
> >> Access violation - code c0000005 (!!! second chance !!!)
> >> eax=e1291208 ebx=80062000 ecx=1fffffff edx=8006e344 esi=80067aa0
> >> edi=3ffffffe
> >> eip=804ef7c7 esp=fb674ae4 ebp=fb674b04 iopl=0 nv up ei pl nz na
> >> pe
> >> nc
> >> cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000
> >> efl=00000306
> >> nt!MiFindExportedRoutineByName+0x54:
> >> 804ef7c7 8b348a mov esi,dword ptr [edx+ecx4]
> >> ds:0023:0006e340=???
> >> kd> r ecx=2f
> >> kd> r
> >> eax=e1291208 ebx=80062000 ecx=0000002f edx=8006e344 esi=80067aa0
> >> edi=3ffffffe
> >> eip=804ef7c7 esp=fb674ae4 ebp=fb674b04 iopl=0 nv up ei pl nz na
> >> pe
> >> nc
> >> cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000
> >> efl=00000306
> >> nt!MiFindExportedRoutineByName+0x54:
> >> 804ef7c7 8b348a mov esi,dword ptr [edx+ecx*4]
> >> ds:0023:8006e400=0000ca7c
> >> kd> g
> >>
> >>
> >> regards
> >>
> >> raj_r
> >>
> >>
> >>
> >> On 6/2/07, xxxxx@microsoft.com wrote:
> >>> Meant to get to this, but had to leave earlier (school play).
> >>>
> >>> Re-reading some of the earlier requests, I’ll be more specific, because
> >>> I
> >>> think it helps explain the reason I still think x64 deserves another
> >>> look
> >>> based upon the other reports. I also think it might help people like
> >>> Bill McKenzie who might still be concerned exactly which calls they have
> >>> to worry about.
> >>>
> >>> The algorithm is:
> >>>
> >>> Low, Middle, High- indices into an ordered array. Target is the value
> >>> you are trying to find the appropriate index for in the array.
> >>>
> >>> Begin with Low at the first entry, High at the last.
> >>>
> >>> while (High >=Low)
> >>> {
> >>> Middle = Low + ((High - Low) >> 1);
> >>> if (Array[Middle] == Target)
> >>> break;
> >>> if (Array[Middle] < Target)
> >>> Low = Middle + 1;
> >>> else
> >>> High = Middle - 1;
> >>> }
> >>>
> >>> if (High < Low) on exit, the value isn’t there- otherwise, Middle is
> >>> your
> >>> desired index.
> >>>
> >>> In this case, the target is a null-terminated character string, the
> >>> array
> >>> elements are offsets from a known base (base of the image) to
> >>> null-terminated strings, and the comparisons are via strcmpi (I think-
> >>> might be strcmp, I’m at home at the moment, and I don’t think that
> >>> detail
> >>> affects the dsicussion significantly).
> >>>
> >>> The specific indices at start will be low = 0, high = number of names
> >>> exported - 1;
> >>>
> >>> If all the High, Middle, Low are signed, this works. If they are
> >>> unsigned, then there is a broken edge- normally when a value is not
> >>> present the final check will have high == middle == low, and fail with
> >>> low incremented above high, or high decremented below low as the case
> >>> may
> >>> be.
> >>>
> >>> But unsigned with Low 0, and the target is still smaller, you get an
> >>> underflow (the new high is 0 (Middle) - 1 and that value is > 0 (Low))
> >>> and this is the bug (easily fixed by using signed indices). While there
> >>> can be other theoretical complications if you wish to assume mixed
> >>> signed/unsigned indices [even worse if you assume negtive start points],
> >>> they don’t realistically apply- these tables have dozens or at most
> >>> hundreds of entries- the sign bit (which is what kills you) doesn’t come
> >>> into play UNTIL this case is hit.
> >>>
> >>> Rehashing the earlier post, let’s say the first bad ULONG [effectively
> >>> at
> >>> array[-1], thanks to the overflow occuring when converting the Middle
> >>> index of 0x7FFFFFFF to a pointer to ULONG] magically gives us an offset
> >>> within the image, and the data at that location, interpreted as a
> >>> string,
> >>> is BIGGER than our target. Still saying its all unsigned, then Low
> >>> becomes 0x80000000 and middle BFFFFFFF- that resolves to the very same
> >>> index due to overflow /wrap- the point being that I believe this is your
> >>> NULL return case when you see it- it continues to compare the same two
> >>> values until it exits because of the built-in ambiguity of the two high
> >>> bits. It requires one happy circumstance, but one isn’t as hard to
> >>> swallow. Still I’m skeptical this magic value is x86/x64 difference.
> >>> But
> >>> hey, I know what to look for and where, so thanks for the tip…
> >>>
> >>> I think I adequately explained on the previous post why I also have a
> >>> concern with the idea that a valid name is affected. But the above
> >>> explanation might make it easier to understand why I assert there that
> >>> only specific cases can trigger these bad behaviors. I don’t see how
> >>> anything other than a valid HAL name preceding the first kernel name can
> >>> wander into this, and unless you do, everything else works.
> >>>
> >>> I’m at least going to try to satisfy myself about the false negatives.
> >>> Ownership or not, I need this to work…
> >>>
> >>> —
> >>> Questions? First check the Kernel Driver FAQ at
> >>> http://www.osronline.com/article.cfm?id=256
> >>>
> >>> To unsubscribe, visit the List Server section of OSR Online at
> >>> http://www.osronline.com/page.cfm?name=ListServer
> >>>
> >>
> >
> >
>
>
> —
> Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256
>
> To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer
></hal.characteristics></hal.numberofnames></hal.addressofnameordinals></hal.addressofnames></hal.characteristics></hal.numberofnames>