flat assembler
Message board for the users of flat assembler.

Index > Windows > Win64 help

Author
Thread Post new topic Reply to topic
jacko221



Joined: 12 Nov 2005
Posts: 22
jacko221 18 Feb 2006, 12:24
hey everybody,
since i have a 64 bit processor i thought i would install 64 bit Windows. Then i found out i my 16bit fasm programs dont work. So i thought f*ck it im going to go learn win64. So now im trying to code an application which opens the cdrom (below)

Code:
format PE64 GUI
entry start


  start:
        mov r9,  0            
        lea r8,  [_caption]        
        lea rdx, [_message]         
        mov rcx,  0                   
        call [MessageBoxA]          

;messagebox shows fine
;from here it crashes and complains
        mov r8, 0             
        mov r9, 0             
        mov r10,0             
        lea rdx, [_cmd_open]        
        call [mciSendStringA]   

        mov r8,  0                    
        mov r9,  0                    
        mov r10, 0                    
        lea rdx, [_cmd_eject]   
        call [mciSendStringA]   

        mov r8,  0                    
        mov r9,  0                    
        mov r10, 0                    
        lea rdx, [_cmd_close]    
        call [mciSendStringA]    
 
                mov ecx, 0
                call [ExitProcess]


section '.data' data readable writeable

_message db 'Do you need additional place for the beer? no? well you have no choice',0
_caption db 'Desktop configuration',0

_cmd_open db 'open cdaudio',0
_cmd_eject db 'set cdaudio door open',0
_cmd_close db 'close cdaudio',0


section '.idata' import data readable writeable

  dd 0,0,0,RVA user_name,RVA user_table
  dd 0,0,0,RVA kernel_name,RVA kernel_table
  dd 0,0,0,RVA winmm_name,RVA winmm_table
  dd 0,0,0,0,0

  user_table:
    MessageBoxA dq RVA _MessageBoxA
    dq 0
  kernel_table:
    ExitProcess dq RVA _ExitProcess
    dq 0
  winmm_table:
    mciSendStringA dq RVA _mciSendStringA
    dq 0


  user_name db 'USER32.DLL',0
  kernel_name db 'KERNEL32.DLL',0
  winmm_name db 'WINMM.DLL',0

; user32.dll:
  _MessageBoxA dw 0
    db 'MessageBoxA',0
; kernel32.dll:
  _ExitProcess dw 0
    db 'ExitProcess',0

; winmm.dll:
  _mciSendStringA dw 0
    db 'mciSendStringA', 0
    


coding MessageBoxA and mciSendStringA in win32 i could just use 'invoke' or push thier parameters to the stack and call it. But why can't i do either in win64?

if anyone could help me understand this and/or fix the problem in this code
i would greatly appreciate it.

Thanks, Jack

P.S: sorry for flooding you with stupid questions and annoying posts. But this seems to be the only way i can learn fasm due to a lack of resources it has.
Post 18 Feb 2006, 12:24
View user's profile Send private message Reply with quote
jacko221



Joined: 12 Nov 2005
Posts: 22
jacko221 19 Feb 2006, 02:15
dw i fixed the problem Smile i found out how to use the stack. Also i made a couple of errors. First off i forgot 'section '.code' code readable executable writeable ', then i named '_mciSendString' : '_mciSendStringA' in which im not 100% sure was apart of the problem.

Code:
format PE64 GUI
entry start

section '.code' code readable executable writeable


  start:
  sub rsp, 4*8
  mov qword [rsp+4*8], 0
  mov qword [rsp+3*8], 0
  mov qword [rsp+3*8], 0
  lea rcx, [_cmd_open]
  call [mciSendString]

  mov qword [rsp+4*8], 0
  mov qword [rsp+3*8], 0
  mov qword [rsp+3*8], 0
  lea rcx, [_cmd_eject]
  call [mciSendString]

  mov qword [rsp+4*8], 0
  mov qword [rsp+3*8], 0
  mov qword [rsp+3*8], 0
  lea rcx, [_cmd_close]
  call [mciSendString]

  mov ecx, 0
  call [ExitProcess]





section '.data' data readable writeable

_message db 'Do you need additional place for the beer? no? well you have no choice',0
_caption db 'Desktop configuration',0

_cmd_open db 'open cdaudio',0
_cmd_eject db 'set cdaudio door open',0
_cmd_close db 'close cdaudio',0


section '.idata' import data readable writeable

  dd 0,0,0,RVA user_name,RVA user_table
  dd 0,0,0,RVA kernel_name,RVA kernel_table
  dd 0,0,0,RVA winmm_name,RVA winmm_table
  dd 0,0,0,0,0

  user_table:
    MessageBoxA dq RVA _MessageBoxA
    dq 0
  kernel_table:
    ExitProcess dq RVA _ExitProcess
    dq 0
  winmm_table:
    mciSendString dq RVA _mciSendString
    dq 0


  user_name db 'USER32.DLL',0
  kernel_name db 'KERNEL32.DLL',0
  winmm_name db 'WINMM.DLL',0

; user32.dll:
  _MessageBoxA dw 0
    db 'MessageBoxA',0
; kernel32.dll:
  _ExitProcess dw 0
    db 'ExitProcess',0

; winmm.dll:
  _mciSendString dw 0
    db 'mciSendStringA', 0
    


one note is that i got rid of the message box because it doesnt want to work. I think that has something to do with rcx.


Last edited by jacko221 on 19 Feb 2006, 02:24; edited 2 times in total
Post 19 Feb 2006, 02:15
View user's profile Send private message Reply with quote
r22



Joined: 27 Dec 2004
Posts: 805
r22 19 Feb 2006, 02:16
You goofed up on the calling convention.
In Win64 for the first 4 arguments are passed to an api with RCX, RDX, R8, and R9. You did this correctly for the MessageBoxA call but then you made up you're own convention for the other calls Very Happy

Here's a corrected version of your code.
Code:
format PE64 GUI
entry start 


  start: 
        mov r9,  4
        lea r8,  [_caption]         
        lea rdx, [_message]          
        mov rcx,  0                    
        call [MessageBoxA]           
        cmp eax,6 ;;is yes?
        jne .END_PROGRAM
;messagebox shows fine 
;from here it crashes and complains 
        mov r8, 0              
        mov r9, 0              
        mov rdx,0
        lea rcx, [_cmd_open]
        call [mciSendStringA]    

        mov r8,  0                     
        mov r9,  0                     
        mov rdx, 0
        lea rcx, [_cmd_eject]
        call [mciSendStringA]    

        mov r8,  0                     
        mov r9,  0                     
        mov rdx, 0
        lea rcx, [_cmd_close]
        call [mciSendStringA]     
             .END_PROGRAM:
                mov ecx, 0 
                call [ExitProcess] 


section '.data' data readable writeable 

_message db 'Do you need additional place for the beer? no? well you have no choice',0 
_caption db 'Desktop configuration',0 

_cmd_open db 'open cdaudio',0 
_cmd_eject db 'set cdaudio door open',0 
_cmd_close db 'close cdaudio',0 


section '.idata' import data readable writeable 

  dd 0,0,0,RVA user_name,RVA user_table 
  dd 0,0,0,RVA kernel_name,RVA kernel_table 
  dd 0,0,0,RVA winmm_name,RVA winmm_table 
  dd 0,0,0,0,0 

  user_table: 
    MessageBoxA dq RVA _MessageBoxA 
    dq 0 
  kernel_table: 
    ExitProcess dq RVA _ExitProcess 
    dq 0 
  winmm_table: 
    mciSendStringA dq RVA _mciSendStringA 
    dq 0 


  user_name db 'USER32.DLL',0 
  kernel_name db 'KERNEL32.DLL',0 
  winmm_name db 'WINMM.DLL',0 

; user32.dll: 
  _MessageBoxA dw 0 
    db 'MessageBoxA',0 
; kernel32.dll: 
  _ExitProcess dw 0 
    db 'ExitProcess',0 

; winmm.dll: 
  _mciSendStringA dw 0 
    db 'mciSendStringA', 0
    
Post 19 Feb 2006, 02:16
View user's profile Send private message AIM Address Yahoo Messenger Reply with quote
jacko221



Joined: 12 Nov 2005
Posts: 22
jacko221 19 Feb 2006, 02:22
Quote:

In Win64 for the first 4 arguments are passed to an api with RCX, RDX, R8, and R9.


Thanks man, that clear it up alot, really appreciate your help.
Post 19 Feb 2006, 02:22
View user's profile Send private message Reply with quote
Feryno



Joined: 23 Mar 2005
Posts: 503
Location: Czech republic, Slovak republic
Feryno 20 Feb 2006, 09:28
And you can reduce bytes of code because you know that operation with 32-bit reg is zero extended to 64-bit
xor ecx,ecx for zeroing RCX reg and has only 2 byte opcode (the some with xor rcx,rcx has 3 bytes)
mov r9d,4 (6 bytes) is smaller than mov r9,4 (7 bytes)
xor r8,r8 has 3 bytes as well xor r8d,r8d here isn't any size optimalization

start:
sub rsp,4*8
this is very necessary at begin of each procedure as well at startup of exe because API may use and destroy 4 qwords of stack at [rsp], [rsp+8*1],[rsp+8*2],[rsp+8*3]
(API parameters 5th and above are 5th at [rsp+8*4], 6th at [rsp+8*5]...).
RSP is misaligned 16 at exe startup as well procedure begin. There are some APIs sensitive for RSP aligned 16 at point of call [API] - because sensitive API use movdqa instruction for access stack. You can avoid this conflict by subtracting nonparity power of 8 or by push nonparity number of regs, e.g.
exe_startup:
sub rsp,8*5 ;make RSP aligned 16
...
call [API]
call procedure0
...
call [ExitProcess]
procedure0:
push rbx ; make RSP aligned 16
sub rsp,8*10
...
call [API]
add rsp,8*10
pop rbx
ret

Today there aren't so high number of APIs sensitive to stack align 16 as they were in days of beta releases of win64 (they were free for download...), but they still exist. It seems that win64 has a special exception handler - e.g. RSP = 6FE18h, movdqa xmm2,[rsp+40h] cause exception and win64 patch this to movdqu xmm2,[rsp+40h] so your program continue and you notice nothing. You notice it only when debugging because debugger replace OS exception handler with own one and debugger stops in DLL at instruction of movdqa.
Post 20 Feb 2006, 09:28
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2023, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.