The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: ragdog on October 13, 2010, 01:29:18 PM

Title: FindNextFile Bug?
Post by: ragdog on October 13, 2010, 01:29:18 PM
Hi

I Programming a little with FindFirstFile and FindNextFile now have i a problem with my counter.
I add a counter and push and pop ecx to the stack.
Use i the register ecx works my counter not correct replace i this to esi or other register,
works this correct why?

I have look in the kernel32.dll (win7) with Ollydbg at 75EAA977
And see the ecx if not pushed or poped !!

If this an Bug of FindNextFile by Windows 7?

Here is my code


Scan proc uses edi ecx
LOCAL buffer[MAX_PATH]:BYTE
LOCAL wfd:WIN32_FIND_DATA
LOCAL hwfd:DWORD

invoke lstrcpy,addr buffer,addr hPath
invoke lstrcat,addr buffer,CTEXT ("/*.*")
invoke FindFirstFile,addr buffer,addr wfd
.if eax!=INVALID_HANDLE_VALUE
mov hwfd,eax
xor ecx,ecx
    .while (eax!=0) && (ecx<3)
               lea   edi,wfd.cFileName
    invoke   AddItem,edi,1
               inc   ecx
    invoke   FindNextFile,hwfd,addr wfd
        .endw
;No more matches, close handle
invoke FindClose,hwfd
.endif
ret
Scan endp



Greets,
Title: Re: FindNextFile Bug?
Post by: evlncrn8 on October 13, 2010, 02:37:46 PM
the api calls probably destroy the ecx register.. push it before the api call and pop it after...

and i think...



xor ecx,ecx  ; ecx is zero here, making the code below useless as ecx will be zero and definately less than 3...

    .while (eax!=0) && (ecx<3)



is wrong..
Title: Re: FindNextFile Bug?
Post by: box on October 13, 2010, 02:43:31 PM


xor ecx,ecx  ; ecx is zero here, making the code below useless as ecx will be zero and definately less than 3...

    .while (eax!=0) && (ecx<3)



This is fine, it's just FindNextFile trashing ecx. Most win API functions only preserve ebx/esi/edi I believe.
Title: Re: FindNextFile Bug?
Post by: ragdog on October 13, 2010, 02:51:29 PM
@evlncrn8

xor ecx,ecx  ; This fill ecx with zero

    .while (eax!=0) && (ecx<3) ;if ecx less than 3 inc ecx . if ecx greater then jmp out of the loop
     ...
      ..
      inc ecx
    .endw

Yes this api destroy the ecx register ,and use ecx without push ecx in to stack or pop ecx from stack

Title: Re: FindNextFile Bug?
Post by: ToutEnMasm on October 13, 2010, 04:49:13 PM

preservation rule
only EBX EDI ESI  are returned without changes.
Your proc must do the same thing     (unproc PROC uses ebx esi edi machin:DWORD)
Title: Re: FindNextFile Bug?
Post by: dedndave on October 13, 2010, 05:26:28 PM
Quotepreservation rule
only EBX EDI ESI  are returned without changes.
oh - and EBP
oh - and the direction flag
Title: Re: FindNextFile Bug?
Post by: ragdog on October 13, 2010, 05:57:57 PM
@ToutEnMasm

I understand not correct what you mean with it :'(
Title: Re: FindNextFile Bug?
Post by: jj2007 on October 13, 2010, 08:49:03 PM
Quote from: dedndave on October 13, 2010, 05:26:28 PM
oh - and the direction flag

That would be worth a test - try calling some APIs with the flag set :bg
Title: Re: FindNextFile Bug?
Post by: RuiLoureiro on October 13, 2010, 09:06:03 PM
ragdog,
            Why to use ECX ? Why not EBX ?
            Replace ECX by EBX and try again. Is there a bug ?
Rui
Title: Re: FindNextFile Bug?
Post by: Tedd on October 13, 2010, 10:10:10 PM
Quote from: ragdog on October 13, 2010, 05:57:57 PM
@ToutEnMasm
I understand not correct what you mean with it :'(
He means: when you call an API function, it may change the values in registers <EAX>, ECX, EDX, but not in EBX, ESI, EDI - so, if you need the values of eax/ecx/edx, you must save them yourself outside of the function call.
This is standard for (almost) all API functions.
Title: Re: FindNextFile Bug?
Post by: ragdog on October 13, 2010, 10:12:25 PM
@RuiLoureiro

Yes i can use edi ebx or anything

I use always ecx as counter and have found this problem

This is a rule of thumb Mnemonics and i coding with it

EAX =Accumulator
EBX = Base
ECX = Counter
EDX =Destination

ESI = Source index
EDI = Destination index
EBP =Base Pointer
ESP =Stack Pointer
EIP =Instructions pointer
ESP = Stack pointer


Thanks Tedd

Quoteyou must save them yourself outside of the function call.

You mean before i call a api push my register to the stack?

Greets
Title: Re: FindNextFile Bug?
Post by: Tedd on October 13, 2010, 10:15:30 PM
Quote from: jj2007 on October 13, 2010, 08:49:03 PM
Quote from: dedndave on October 13, 2010, 05:26:28 PM
oh - and the direction flag
That would be worth a test - try calling some APIs with the flag set :bg
I'd guess the notion isn't so much of preserving the direction flag as assuming it will, and should always be, cleared (string operations increment the index registers.) So, if a function internally sets it, it will 'restore' the value by clearing it again, even if it was in fact set to begin with.
Title: Re: FindNextFile Bug?
Post by: Tedd on October 13, 2010, 10:16:51 PM
Quote from: ragdog on October 13, 2010, 10:12:25 PM
You mean before i call a api push my register to the stack?
Yes - but usually only for eax, ecx, edx.

Also, don't worry so much about the 'definitions' for the registers - they are all general purpose (except for a few cases) and can be used in any way.
Title: Re: FindNextFile Bug?
Post by: ragdog on October 13, 2010, 10:53:07 PM
Thanks
Title: Re: FindNextFile Bug?
Post by: dedndave on October 13, 2010, 11:03:21 PM
i don't suggest saving and restoring the eflags register
only - if you set the direction flag, be sure and clear it before you call an API
and clear it when your function is complete
in fact, i had a case where sometimes the direction flag needed to be set and sometimes it didn't
i pushed the eflags register and popped it into a general register, then tested the state of the DF
if it was clear, i did nothing - if it was set, i cleared it with CLD
that seemed to work better than simply pushing and popping the eflags register
POPFD, CLD, and STD are slow instructions
        pushfd
        pop     eax
        test    ah,4
        jz      @F

        cld

@@:
Title: Re: FindNextFile Bug?
Post by: jj2007 on October 13, 2010, 11:20:36 PM
Interesting technique, Dave. On my Celeron, it is slower than a simple cld, though:

Intel(R) Celeron(R) M CPU        420  @ 1.60GHz (SSE3)
127     cycles for 10*pushfd+cld
72      cycles for 10*simple cld
Title: Re: FindNextFile Bug?
Post by: dedndave on October 14, 2010, 12:27:56 AM
that's true, of course, if the flag is set
try it for a 50/50 set/not set   :bg