Related Projects > NASMX

BUG of "USES MARCO"

(1/3) > >>

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