Author Topic: FINDFIRSTFILE problem  (Read 382 times)

markallyn

  • Member
  • **
  • Posts: 236
FINDFIRSTFILE problem
« on: September 20, 2021, 08:12:18 AM »
Hello,

I've run into a problem attempting to call findfirstfile.  Searching the web has yielded nothing, but I did come up with an old post by Vortex submitted to this site on January 9, 2017.  Although Vortex wrote in POASM and I'm using ml64/link Vortex's example seems to me to show that what I'm trying to do isn't nuts.

Here"s the code:
Quote

includelib   ..\masm32\lib64\msvcrt.lib
includelib   ..\masm32\lib64\kernel32.lib

include myincludes64.INC

FindFirstFileA  PROTO   :QWORD, :QWORD
FindClose   PROTO    :QWORD

.data
filname   db   "gs.asm"
wfd     WIN32_FIND_DATA < >   

.data?
hndl   QWORD   ?

.code
main   PROC
sub   rsp,   40h
lea   rcx,   filname
lea   rdx,    wfd
call    FindFirstFileA
mov   hndl,   rax
mov   rcx,   hndl
call   FindClose
add   rsp,   40h
ret
main   ENDP
END

I included MSVCRT only because I had a plan to use some of the functions there; as you can see, the program doesn't call any of them.  The myincludes64.inc file contains the two necessary structures.  They are as follows:

Quote
FILETIME   struct
dwLowDateTime   DWORD   ?
dwHighDateTime   DWORD   ?
FILETIME   ends

...And:
Quote
WIN32_FIND_DATAA   struct
dwFileAttributes   DWORD   ?
ftCreationTime   FILETIME   <>
ftLastAccessTime   FILETIME   <>
ftLastWriteTime   FILETIME   <>
nFileSizeHigh   DWORD   ?
nFileSizeLow   DWORD   ?
dwReserved0   DWORD   ?
dwReserved1   DWORD   ?
cFileName   CHAR MAX_PATH dup (?)
cAlternateFileName   CHAR 14 dup (?)
WIN32_FIND_DATAA   ends

The program compiles and links successfully.  It also appears to run.  But, when the program hits the call to findfirstfileA it goes off into never-never land.  Doesn't even return an error code in RAX.

I've worked on this several days with no success.  I'd really like to get the bug out.

Regards,

Mark Allyn

HSE

  • Member
  • *****
  • Posts: 1815
  • AMD 7-32 / i3 10-64
Re: FINDFIRSTFILE problem
« Reply #1 on: September 20, 2021, 09:27:25 AM »
filename db "gs.asm",0

markallyn

  • Member
  • **
  • Posts: 236
Re: FINDFIRSTFILE problem
« Reply #2 on: September 20, 2021, 09:41:46 AM »
HSE,

Among the many things I have tried was zero-terminating the file name.  Just tried it again.  It still doesn't work.

Thanks, though, for the suggestion!

Mark


nidud

  • Member
  • *****
  • Posts: 2307
    • https://github.com/nidud/asmc
Re: FINDFIRSTFILE problem
« Reply #3 on: September 20, 2021, 10:35:45 AM »

    sub rsp,40
    ...
    add rsp,40

markallyn

  • Member
  • **
  • Posts: 236
Re: FINDFIRSTFILE problem
« Reply #4 on: September 20, 2021, 10:48:39 AM »
Hi Nidud,

I haven't completely checked yet, but a quick glance at x64dbg indicates that you have fixed the problem.  Will do more checking tomorrow morning.

You could do me a huge favor if you could briefly explain why this seemingly small change would have such a huge and beneficial impact.

Again, many thanks for looking this over.

Regards,
Mark Allyn

InfiniteLoop

  • Regular Member
  • *
  • Posts: 17
Re: FINDFIRSTFILE problem
« Reply #5 on: September 20, 2021, 02:43:10 PM »
sub rsp, 64 is not 16-byte aligned but sub 40 is ?

nidud

  • Member
  • *****
  • Posts: 2307
    • https://github.com/nidud/asmc
Re: FINDFIRSTFILE problem
« Reply #6 on: September 20, 2021, 07:00:10 PM »
sub rsp, 64 is not 16-byte aligned but sub 40 is ?

Yes. The stack has to be align 16 on call which means it's always off by 8 on entry (return address added).

main:
    sub     rsp,8   ; align 16
    sub     rsp,4*8 ; adding stack space for args - an even number (min 4)
    call    ...
    sub     rsp,4*8 ; 5 * 8 = 40
    sub     rsp,8
    ret

Using Base Pointer:

    push    rbp     ; align 16
    mov     rbp,rsp
    sub     rsp,32  ; shadow space
    call    ...
    leave
    ret

Enter stack:

    enter   32,0
    call    ...
    leave
    ret

markallyn

  • Member
  • **
  • Posts: 236
Re: FINDFIRSTFILE problem
« Reply #7 on: September 20, 2021, 08:43:00 PM »
Good morning Nidud and InfiniteLoop,

Well, so if I had done like this:

Quote
  and rsp, -10h
  sub rsp, 40h

..it would have been OK?  As I read your responses I could have subtracted any amount from rsp as long as it wsa divisible by 8?

Nidud's main doesn't add back 40d before the ret instruction.  Why not?

And in Nidud's "Using base pointer" and "Enter stack" doesn't add or sub anything.  Is this because he "leaves" before the ret?

Obviously I need to understand the stack better.  I apologize for these very elementary questions.

Regards,
Mark Allyn


nidud

  • Member
  • *****
  • Posts: 2307
    • https://github.com/nidud/asmc
Re: FINDFIRSTFILE problem
« Reply #8 on: September 20, 2021, 09:26:58 PM »
Well, so if I had done like this:

Quote
  and rsp, -10h
  sub rsp, 40h

..it would have been OK?

Yes.

Quote
  As I read your responses I could have subtracted any amount from rsp as long as it wsa divisible by 8?

Yes, min 4*8 and large enough to hold the max number of arguments used + alignment.

Quote
Nidud's main doesn't add back 40d before the ret instruction.  Why not?

It actually does, but yes, why not.

Quote
And in Nidud's "Using base pointer" and "Enter stack" doesn't add or sub anything.  Is this because he "leaves" before the ret?

Yes, the LEAVE instruction set RSP to RBP and pop RBP.

Quote
Obviously I need to understand the stack better.  I apologize for these very elementary questions.

Also note that if you add an argument to the proc ML inserts a standard stack frame.

main proc argc:sdword
    push    rbp
    mov     rbp,rsp

    ...
    leave
    ret

markallyn

  • Member
  • **
  • Posts: 236
Re: FINDFIRSTFILE problem
« Reply #9 on: September 21, 2021, 12:56:44 AM »
Good morning once again, NIDUD,

Your tutorials have been very helpful.  I knew about spill space but I didn't understand the necessity of aligning the stack prior to the call.  I assumed, as you can see, that sub 64 (40h), because it is divisible by 8 and also allowed for plenty of spill and some parms, would do the job.  Not so!

Given my naivete we will no doubt meet again in future.

Regards,
Mark Allyn