flat assembler
Message board for the users of flat assembler.
Index
> Windows > emit macro not show MessageBox!! |
Author |
|
revolution 28 Dec 2018, 18:58
When I delete the line "include 'avx2.inc'" it assembles for me okay.
|
|||
28 Dec 2018, 18:58 |
|
catafest 30 Dec 2018, 14:44
Yes! the include 'avx2.inc' is not the part of the issue in this moment
I start with this worked code: Code: format PE64 GUI include "win64ax.inc" .data Caption db 'Win64 assembly program',0 Message db 'Hello World!',0 .code start: xor r9d,r9d lea r8,[Caption] lea rdx,[Message] xor rcx,rcx call [MessageBox] mov ecx,eax invoke ExitProcess,0 .end start The .data is used just with: include "win64ax.inc" I eliminate source code just for show the MessageBox. but same problem is not show!? Code: format PE64 GUI 4.0 entry start ;=== section '.text' code readable executable ;=== macro emit [inst] { forward inst } ;=== ;include "win64ax.inc" ;=== align 1 no_avx2_text db 'No CPU with AVX',0 no_avx2_mess db 'CPU does not suport AVX2',0 ;=== align 64 init: virtual at 0 rq 12 .k_stack_size = $+16 end virtual push rsi sub rsp,.k_stack_size xor ecx,ecx lea rdx,[no_avx2_mess] lea r8,[no_avx2_text] xor r9d,r9d call [MessageBox] test eax,eax jz .quit .quit: xor ecx,ecx call [ExitProcess] ;=== align 64 start: ;=== virtual at 0 rq 5 .k_stack_size = $+16 end virtual sub rsp,.k_stack_size call init test eax,eax jz .quit .quit: xor ecx,ecx call [ExitProcess] ;=== section '.idata' import data readable writeable _kernel32 db 'kernel32.dll',0 _user32 db 'user32.dll',0 _gdi32 db 'gdi32.dll',0 MessageBox dq rva _MessageBox ExitProcess dq rva _ExitProcess emit <_ExitProcess dw 0>,<db 'ExitProcess',0> emit <_MessageBox dw 0>,<db 'MessageBox',0> |
|||
30 Dec 2018, 14:44 |
|
revolution 30 Dec 2018, 16:07
I see no problem assembling your code.
Code: flat assembler version 1.73.02 (2359008 kilobytes memory) 2 passes, 1536 bytes. |
|||
30 Dec 2018, 16:07 |
|
catafest 30 Dec 2018, 17:09
Yes, Is not the problem with the assembly process for the last source code.
The result should be a MessageBox when I run the executable, but don't show anything. I don't know why (maybe I don't know how to use the virtual). revolution wrote: I see no problem assembling your code. |
|||
30 Dec 2018, 17:09 |
|
revolution 30 Dec 2018, 17:12
Okay. So your problem is a runtime thing.
I expect your stack is not properly aligned. At "start" you can do one of two things. Code: sub rsp,8 ;do this and rsp,-16 ;or this. |
|||
30 Dec 2018, 17:12 |
|
catafest 30 Dec 2018, 17:35
If you refer to this part of source code:
Code: align 64 start: ;=== virtual at 0 rq 5 .k_stack_size = $+16 end virtual sub rsp,.k_stack_size I don't know how to do it in your way. I understand your point to start aligned but for me is ok. See also this link: https://stackoverflow.com/questions/41843715/defining-a-structure-in-fasm-which-of-the-2-ways-is-better-in-what-situation Can you be more specific or show your result source code? revolution wrote: Okay. So your problem is a runtime thing. |
|||
30 Dec 2018, 17:35 |
|
revolution 30 Dec 2018, 17:57
By way of a test, put the line "and rsp,-16" immediately before the MessgeBox call and see if it fixes your problem.
|
|||
30 Dec 2018, 17:57 |
|
bitRAKE 30 Dec 2018, 18:04
I suspect revolution is correct. The stack address needs to be aligned to a 16 byte boundary when calling Windows APIs. You can verify in a debugger like x64dbg, etc.
https://x64dbg.com/#start Windows executes a CALL to your entry point, and this puts the return address on the stack (making the alignment 8 mod 16). So, you'll need to adjust the stack by 8, 8+16, 8+32, etc. bytes before using the API. Some functions might work, but this kind of error will cause a problem eventually. My preferred method is: Code: virtual at rbp-.FRAME rq 4 ; shadow forward .5 rq 1 ; API parameter space .6 rq 1 ; put your function local data here rb (16-(($-$$) AND 15)) AND 15 ; only if padding needed .FRAME:= $-$$ rq 1 ; saved RBP rq 1 ; return address .RCX rq 1 ; our shadow .RDX rq 1 ; our shadow .R8 rq 1 ; our shadow .R9 rq 1 ; our shadow end virtual enter .FRAME,0 mov [.RCX],rsi mov [.RDX],rdi mov [.R8],rbx mov [.R9],r15 Code: mov rsi,[.RCX] mov rdi,[.RDX] mov rbx,[.R8] mov r15,[.R9] leave retn Even if there are no parameters, the shadow space is still required by the API: Code: enter 32,0 call [GetCommandLineA] call [Abort] ; from msvcrt.dll int3 ; no return from above Last edited by bitRAKE on 02 Jan 2019, 07:44; edited 1 time in total |
|||
30 Dec 2018, 18:04 |
|
catafest 30 Dec 2018, 19:07
@revolution: I try to fix with your idea but not worked.
@bitRAKE: about your method (if I understand well): you create FRAME of the stack in order to use. In your example, this FRAME is advance one because you can map (shadow) the registers and more. If you see my full example is similar to your FRAME, maybe the error is linked to shadow space: "It's important to understand that the shadow space belongs to the called function." For some reason, the x64dbg don't let me debug the executable (I'm not very skilled with this debugger). |
|||
30 Dec 2018, 19:07 |
|
Tomasz Grysztar 30 Dec 2018, 19:32
catafest wrote: For some reason, the x64dbg don't let me debug the executable (I'm not very skilled with this debugger). When I tried debugging your sample with FDBG, the exception happens in loader, even before the entry point has chance to be reached. Well, I see where the problem comes from - you do not have a properly built import table. By adapting an example import table from my PE tutorial I get a working executable: Code: format PE64 GUI 4.0 entry start ;=== section '.text' code readable executable ;=== macro emit [inst] { forward inst } ;=== ;include "win64ax.inc" ;=== align 1 no_avx2_text db 'No CPU with AVX',0 no_avx2_mess db 'CPU does not suport AVX2',0 ;=== align 64 init: virtual at 0 rq 12 .k_stack_size = $+16 end virtual push rsi sub rsp,.k_stack_size xor ecx,ecx lea rdx,[no_avx2_mess] lea r8,[no_avx2_text] xor r9d,r9d call [MessageBox] test eax,eax jz .quit .quit: xor ecx,ecx call [ExitProcess] ;=== align 64 start: ;=== virtual at 0 rq 5 .k_stack_size = $+16 end virtual sub rsp,.k_stack_size call init test eax,eax jz .quit .quit: xor ecx,ecx call [ExitProcess] ;=== section '.idata' import data readable writeable ImportTable: .1.ImportLookupTableRva dd RVA KernelLookupTable .1.TimeDateStamp dd 0 .1.ForwarderChain dd 0 .1.NameRva dd RVA KernelDLLName .1.ImportAddressTableRva dd RVA KernelAddressTable .2.ImportLookupTableRva dd RVA UserLookupTable .2.TimeDateStamp dd 0 .2.ForwarderChain dd 0 .2.NameRva dd RVA UserDLLName .2.ImportAddressTableRva dd RVA UserAddressTable dd 0,0,0,0,0 KernelLookupTable: dq RVA ExitProcessLookup dq 0 KernelAddressTable: ExitProcess dq RVA ExitProcessLookup ; this is going to be replaced with the address of the function dq 0 UserLookupTable: dq RVA MessageBoxALookup dq 0 UserAddressTable: MessageBox dq RVA MessageBoxALookup ; this is going to be replaced with the address of the function dq 0 align 2 ExitProcessLookup: .Hint dw 0 .Name db 'ExitProcess',0 align 2 MessageBoxALookup: .Hint dw 0 .Name db 'MessageBoxA',0 KernelDLLName db 'KERNEL32.DLL',0 UserDLLName db 'USER32.DLL',0 ImportTable.End: |
|||
30 Dec 2018, 19:32 |
|
bitRAKE 30 Dec 2018, 19:36
That's okay, we can walk through the code in our minds:
Let us start at "start". How much do you subtract from RSP? 56 Stack is 8 mod 16, and 56 = 8 mod 16. Which is 8+8 mod 16 ~ 0 mod 16, (Stack is aligned at this point) Next you CALL "init" - stack is NOT aligned. In "init", we PUSH RSI, stack is again aligned! Then SUB RSP,12*8 + 16, stack is still aligned! Stack alignment is not the problem. Maybe, your IAT is missing some data? Valid IAT looks like... Code: section '.idata' import data readable writeable dd 0,0,0,RVA comctl32_name,RVA comctl32_table dd 0,0,0,RVA kernel32_name,RVA kernel32_table dd 0,0,0,RVA ole32_name,RVA ole32_table dd 0,0,0,RVA user32_name,RVA user32_table dd 0,0,0,0,0 comctl32_table: InitCommonControlsEx dq RVA _InitCommonControlsEx dq 0 kernel32_table: ExitProcess dq RVA _ExitProcess LoadLibraryA dq RVA _LoadLibraryA dq 0 ole32_table: CoInitializeEx dq RVA _CoInitializeEx CoUninitialize dq RVA _CoUninitialize dq 0 user32_table: DialogBoxParamW dq RVA _DialogBoxParamW EndDialog dq RVA _EndDialog GetDlgItem dq RVA _GetDlgItem MoveWindow dq RVA _MoveWindow SendMessageW dq RVA _SendMessageW SetFocus dq RVA _SetFocus dq 0 comctl32_name db 'comctl32',0 kernel32_name db 'kernel32',0 msftedit_name db "msftedit",0 ole32_name db 'ole32',0 user32_name db 'user32',0 _InitCommonControlsEx dw 0 db 'InitCommonControlsEx',0 _ExitProcess dw 0 db 'ExitProcess',0 _LoadLibraryA dw 0 db 'LoadLibraryA',0 _CoInitializeEx dw 0 db 'CoInitializeEx',0 _CoUninitialize dw 0 db 'CoUninitialize',0 _DialogBoxParamW dw 0 db 'DialogBoxParamW',0 _EndDialog dw 0 db 'EndDialog',0 _GetDlgItem dw 0 db 'GetDlgItem',0 _MoveWindow dw 0 db 'MoveWindow',0 _SendMessageW dw 0 db 'SendMessageW',0 _SetFocus dw 0 db 'SetFocus',0 |
|||
30 Dec 2018, 19:36 |
|
catafest 30 Dec 2018, 20:16
Thank you! The problem was "the import table".
@Tomasz Grysztar - your source code working well The debugger x96dbg show the RIP points strange (versus a simple example) that can be a clue. I will try to follow the links and classic examples macros. @bitRAKE - not work with your table ( the new error jump to call[MessageBox]) |
|||
30 Dec 2018, 20:16 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.