Author Topic: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?  (Read 877 times)

nidud

  • Member
  • *****
  • Posts: 2213
    • https://github.com/nidud/asmc
The point was the loading of arguments: left-to-right versus right-to-left.

The masm64 project is a set of macros, not an assembler. It includes among other things an INVOKE macro that loads arguments from left-to-right. The question is then where does this idea come from?

Most likely the answer is JWasm which was the first assembler (as far as I know) with a 64-bit INVOKE directive.

TouEnMasm

  • Member
  • *****
  • Posts: 1805
    • EditMasm
Re: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
« Reply #1 on: March 04, 2021, 02:18:18 AM »
A working sample,using full path who is the key.
Code: [Select]
main proc
;--------- work with full path ------------------------
invoke GetModuleFileName,NULL,addr AppPath,MAX_PATH
invoke PathFindFileName,addr AppPath
mov byte ptr [rax],0
invoke lstrcat,addr AppPath,addr szFileName
invoke printf ,addr AppPath
;------------------------------- TOO FEW arguments to invoke -----------------------------------
invoke CreateFile,addr AppPath,GENERIC_READ,NULL,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL ; Attempt to access file: TESTFILE.bin for reading!
mov hFile, rax ; If successful, copy "file handle" in RAX to hFile.

; A couple examples for checking the RETURN VALUE from the API:

.if hFile == INVALID_HANDLE_VALUE
mov r11,0
invoke printf ,TXT(13,10,"CreateFileA FAILED")
.else
invoke printf ,TXT(13,10,"CreateFileA REUSSITE")
invoke CloseHandle,hFile
.endif
ret      ;it's enough
main endp

in pure assembler:
Quote
main:
  0000000000000000: 48 83 EC 48        sub         rsp,48h
  0000000000000004: 33 C9              xor         ecx,ecx
  0000000000000006: 48 8D 15 00 00 00  lea         rdx,[AppPath]
                    00
  000000000000000D: 41 B8 04 01 00 00  mov         r8d,104h
  0000000000000013: E8 00 00 00 00     call        GetModuleFileNameA
  0000000000000018: 48 8D 0D 00 00 00  lea         rcx,[AppPath]
                    00
  000000000000001F: E8 00 00 00 00     call        PathFindFileNameA
  0000000000000024: C6 00 00           mov         byte ptr [rax],0
  0000000000000027: 48 8D 0D 00 00 00  lea         rcx,[AppPath]
                    00
  000000000000002E: 48 8D 15 00 00 00  lea         rdx,[szFileName]
                    00
  0000000000000035: E8 00 00 00 00     call        lstrcatA
  000000000000003A: 48 8D 0D 00 00 00  lea         rcx,[AppPath]
                    00
  0000000000000041: E8 00 00 00 00     call        printf
  0000000000000046: 48 8D 0D 00 00 00  lea         rcx,[AppPath]
                    00
  000000000000004D: BA 00 00 00 80     mov         edx,80000000h
  0000000000000052: 45 33 C0           xor         r8d,r8d
  0000000000000055: 45 33 C9           xor         r9d,r9d
  0000000000000058: C7 44 24 20 03 00  mov         dword ptr [rsp+20h],3
                    00 00
  0000000000000060: C7 44 24 28 80 00  mov         dword ptr [rsp+28h],80h
                    00 00
  0000000000000068: 48 C7 44 24 30 00  mov         qword ptr [rsp+30h],0
                    00 00 00
  0000000000000071: E8 00 00 00 00     call        CreateFileA
  0000000000000076: 48 89 05 00 00 00  mov         qword ptr [hFile],rax
                    00
  000000000000007D: 48 83 3D 00 00 00  cmp         qword ptr [hFile],0FFFFFFFFFFFFFFFFh
                    00 FF
  0000000000000085: 75 15              jne         000000000000009C
  0000000000000087: 49 C7 C3 00 00 00  mov         r11,0
                    00
  000000000000008E: 48 8D 0D 00 00 00  lea         rcx,[??000C]
                    00
  0000000000000095: E8 00 00 00 00     call        printf
  000000000000009A: EB 18              jmp         00000000000000B4
  000000000000009C: 48 8D 0D 00 00 00  lea         rcx,[??000D]
                    00
  00000000000000A3: E8 00 00 00 00     call        printf
  00000000000000A8: 48 8B 0D 00 00 00  mov         rcx,qword ptr [hFile]
                    00
  00000000000000AF: E8 00 00 00 00     call        CloseHandle
  00000000000000B4: 48 83 C4 48        add         rsp,48h
  00000000000000B8: C3                 ret


Fa is a musical note to play with CL

TouEnMasm

  • Member
  • *****
  • Posts: 1805
    • EditMasm
Re: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
« Reply #2 on: March 04, 2021, 04:04:25 AM »
This one show the file to screen
Code: [Select]
ReafileAsm:
push        rbp
push        rbx
push        rsi
push        rdi
sub         rsp,148h
lea         rbp,[rsp+80h]
;------- end prologue -----------
mov         rcx,qword ptr [hFile]
lea         rdx,[buffer]
mov         r8d,1000h
lea         r9,[rbp-44h]
mov         qword ptr [rsp+20h],0
call        ReadFile
;------------------------------------
lea         rdi,[rbp-40h] ;local phrase
lea         rsi,[buffer]
045:
cmp         byte ptr [rsi],0Ah
je          054
cmp         byte ptr [rsi],0
je          054
movs        byte ptr [rdi],byte ptr [rsi]
jmp         045
jmp         070
054:
cmp         byte ptr [rsi],0Ah
jne         070
movs        byte ptr [rdi],byte ptr [rsi]
mov         byte ptr [rdi],0
lea         r11,[rbp-40h]
lea         rcx,[rbp-40h]
call        printf
;----------------------------------
lea         rdi,[rbp-40h]
jmp         045
070:
;-------- epilogue ---------
lea         rsp,[rbp+0C8h]
pop         rdi
pop         rsi
pop         rbx
pop         rbp
ret

main:
sub         rsp,48h
;---------end prologue ---------------------
xor         ecx,ecx
lea         rdx,[AppPath]
mov         r8d,104h
call        GetModuleFileNameA
;--------------------------------------
lea         rcx,[AppPath]
call        PathFindFileNameA
mov         byte ptr [rax],0
lea         rcx,[AppPath]
lea         rdx,[szFileName]
call        lstrcatA
lea         rcx,[AppPath]
call        printf
lea         rcx,[AppPath]
mov         edx,80000000h
xor         r8d,r8d
xor         r9d,r9d
mov         dword ptr [rsp+20h],3
mov         dword ptr [rsp+28h],80h
mov         qword ptr [rsp+30h],0
call        CreateFileA
mov         qword ptr [hFile],rax
cmp         qword ptr [hFile],0FFFFFFFFFFFFFFFFh
jne         0118
mov         r11,0
lea         rcx,[??000C]
call        printf
jmp         0135
0118:
lea         rcx,[??000D]
call        printf
call        ReafileAsm
mov         rcx,qword ptr [hFile]
call        CloseHandle
0135:
;------- start epilogue -------
add         rsp,48h
ret


https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-160


Fa is a musical note to play with CL

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 8494
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
« Reply #3 on: March 04, 2021, 04:52:48 AM »
 :tongue:
Quote
The masm64 project is a set of macros, not an assembler. It includes among other things an INVOKE macro that loads arguments from left-to-right. The question is then where does this idea come from?

Most likely the answer is JWasm which was the first assembler (as far as I know) with a 64-bit INVOKE directive
The 1990 version of MASM was the first assembler to use "invoke" and it was then 16 bit, 1997 MASM was 32 bit, the much later Watcom derivatives have simply tried to ape 1990 MASM. JWASM in 64 bit was broken and it did not properly comply with the Intel ABI.

The masm64 project uses 64 bit MASM which is a MACRO assembler using much the same pre-processor as the old 16 bit version. Now it is obvious that you don't know much about it as it contains its own format include files, a matching set of IMPORT libraries, its own STATIC library and matching include file and its own set of pre-processor macros that provide a range of stackframe designs, a procedure calling macro that "invoke" is a wrapper to, a lower overhead technique to call procedures and API functions using up to the first 4 registers.

> that loads arguments from left-to-right.

The Windows x64 ABI does not have a load order, it uses the first 4 registers then WRITES arguments to sequential addresses on the stack. You can write them in any order you like as long as you write them in the correct sequence. What you are assuming is out of date 32 bit MASM technology of STDCALL push/call technology.

Attempting to re-write history on the basis of yet another warmed over Watcom derivative is nonsense. Differing from the Watcom derivatives, 64 bit MASM using its own MACRO assembler capacity and is already application ready and produces reliable working 64 bit applications, not little test pieces.
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :skrewy: