Related Projects > NASMX
BUG of "USES MARCO"
ankiller:
proc testProc,dword x,dword y
uses ebx,ecx,edx,esi
locals none
mov eax,1
endproc
OD:
00401034 55 push ebp
00401035 89E5 mov ebp,esp
00401037 895D FC mov dword ptr ss:[ebp-0x4],ebx
0040103A 894D F8 mov dword ptr ss:[ebp-0x8],ecx
0040103D 8955 F4 mov dword ptr ss:[ebp-0xC],edx
00401040 8975 F0 mov dword ptr ss:[ebp-0x10],esi
00401043 83EC 10 sub esp,0x10<--------------------------Here ESP is OK
00401046 B8 01000000 mov eax,0x1
0040104B 83C4 10 add esp,0x10<--------------------------Why add ESP?????
0040104E 5E pop esi ;pop what?
0040104F 5A pop edx ;pop what?
00401050 59 pop ecx ;pop what?
00401051 5B pop ebx ;pop what?
00401052 89EC mov esp,ebp
00401054 5D pop ebp
00401055 C2 0800 retn 0x8
encryptor256:
Confirmed!, i see ghosts the same:
Compile:
--- Code: ---%include "nasmx.inc"
proc testProc,dword x,dword y
uses ebx,ecx,edx,esi
locals none
mov eax,1
endproc
--- End code ---
With: "nasm -f win32 test.asm"
Disassemble with: "ndisasm -b 32 test.obj"
--- Code: ---0000003C 55 push ebp
0000003D 89E5 mov ebp,esp
0000003F 895DFC mov [ebp-0x4],ebx
00000042 894DF8 mov [ebp-0x8],ecx
00000045 8955F4 mov [ebp-0xc],edx
00000048 8975F0 mov [ebp-0x10],esi
0000004B 83EC10 sub esp,byte +0x10
0000004E B801000000 mov eax,0x1
00000053 83C410 add esp,byte +0x10
00000056 5E pop esi
00000057 5A pop edx
00000058 59 pop ecx
00000059 5B pop ebx
0000005A 89EC mov esp,ebp
0000005C 5D pop ebp
0000005D C20800 ret 0x8
--- End code ---
But it works, because of "mov esp,ebp".
"works" = "works" * 0.5 => LRESULT: Not really.
Error report
This code, print register EBX, before and after:
--- Code: ---bits 32
%include "nasmx.inc"
section .data use32
align 4
txt: db 13,10,"Hello world: %d",0
section .text use32
global main
extern printf
align 4
proc testProc,dword x,dword y
uses ebx,ecx,edx,esi
locals none
mov eax,1
endproc
align 4
main:
push ebp
push ebx
mov ebp,esp
; Print current EBX
push ebx
push txt
call printf
add esp,8
; Call TESTPROC
push 0xFEEDBEEF
push 0xCAFEBABE
call testProc
; Print current EBX
push ebx
push txt
call printf
add esp,8
mov esp,ebp
pop ebx
pop ebp
ret
--- End code ---
Produces output:
--- Code: ---Hello world: 2130571264
Hello world: -17973521
--- End code ---
Fix:
This code, print register EBX, before and after:
--- Code: ---bits 32
%include "nasmx.inc"
section .data use32
align 4
txt: db 13,10,"Hello world: %d",0
section .text use32
global main
extern printf
align 4
;proc testProc,dword x,dword y
; uses ebx,ecx,edx,esi
; locals none
; mov eax,1
;endproc
testProc:
push ebp
mov ebp,esp
mov [ebp-0x4],ebx
mov [ebp-0x8],ecx
mov [ebp-0xc],edx
mov [ebp-0x10],esi
sub esp,byte +0x10
mov eax,0x1
pop esi
pop edx
pop ecx
pop ebx
mov esp,ebp
pop ebp
ret 0x8
align 4
main:
push ebp
push ebx
mov ebp,esp
; Print current EBX
push ebx
push txt
call printf
add esp,8
; Call TESTPROC
push 0xFEEDBEEF
push 0xCAFEBABE
call testProc
; Print current EBX
push ebx
push txt
call printf
add esp,8
mov esp,ebp
pop ebx
pop ebp
ret
--- End code ---
Produces output:
--- Code: ---Hello world: 2130571264
Hello world: 2130571264
--- End code ---
Conclusion:
It works, but registers are not saved/restored like it should be.
It would not work, if a stack register, at procedures epilog, would not be restored.
By using "mov esp,ebp" could save nasty surprise for later, like it did now - gotta nasty surprise.
Avoiding of "mov esp,ebp" would show a clear error on the first run, but it didn't,
because, esp, was manually fixed/restored, so, error rised later, like we see, now.
Why:
It seem's it was a small mix with x64 "non-calling convention architecture".
You see, this is some basic x64 procedure model:
--- Code: ---align 16
procedure:
; Prolog
; ...
sub rsp,0x28
; ...
; Epilog
; ...
add rsp,0x28
; ...
ret
--- End code ---
Notify:
sub - allocate stack space at prolog,
add - deallocate stack space at epilog.
...
Yes, but it's for x64.
Final conclusion:
Lines of code:
* add esp,byte +0x10
* mov esp,ebpShould be removed, then, it should work, like it should.
Offtopic, How to compress sentence: "Should be removed, then, it should work, like it should."
Like this:
Assign x = Should
Assign y = it
LRESULT: "X be removed, then, Y X work, like Y X."
Bye,
Encryptor256 @ Error Analysis Department. :D
Frank Kotler:
What would happen if you put "locals none" first and "uses ..." after?
Best,
Frank
encryptor256:
--- Quote from: Frank Kotler on February 24, 2014, 10:55:32 AM ---What would happen if you put "locals none" first and "uses ..." after?
Best,
Frank
--- End quote ---
Code:
--- Code: ---%include "nasmx.inc"
proc testProc,dword x,dword y
locals none
uses ebx,ecx,edx,esi
mov eax,1
endproc
--- End code ---
With: "nasm -f win32 test.asm", produced an error:
--- Code: ---test.asm:5: fatal: (USES:8) uses directive must come before locals directive.
--- End code ---
encryptor256:
Confirm twice, i think, x32 is mixed with a x64 procedure model.
x64 Code:
--- Code: ---bits 64
%include "nasmx.inc"
proc testProc,dword x,dword y
uses rbx,rcx,rdx,rsi
locals none
mov rax,1
endproc
--- End code ---
x64 Compile with: "nasm -f win64 test.asm",
x64 Debug with: "ndisasm -b 64 test.obj"
x64 Result:
--- Code: ---0000003C 55 push rbp
0000003D 4889E5 mov rbp,rsp
00000040 48895DF8 mov [rbp-0x8],rbx
00000044 48894DF0 mov [rbp-0x10],rcx
00000048 488955E8 mov [rbp-0x18],rdx
0000004C 488975E0 mov [rbp-0x20],rsi
00000050 4883EC20 sub rsp,byte +0x20
00000054 B801000000 mov eax,0x1
00000059 4883C420 add rsp,byte +0x20
0000005D 5E pop rsi
0000005E 5A pop rdx
0000005F 59 pop rcx
00000060 5B pop rbx
00000061 4889EC mov rsp,rbp
00000064 5D pop rbp
00000065 C3 ret
--- End code ---
Nice easter egg, can this even work? :D
So,
rsp - 0x20 ; sub rsp,byte +0x20
rsp + 0x20 ; add rsp,byte +0x20
rsp + 0x08 ; pop rsi
rsp + 0x08 ; pop rdx
rsp + 0x08 ; pop rcx
rsp + 0x08 ; pop rbx
Stack undeflow or overflow?
It's called a stack undeflow.
Bye.
Navigation
[0] Message Index
[#] Next page
Go to full version