NASM - The Netwide Assembler
NASM Forum => Using NASM => Topic started by: nobody on January 12, 2009, 04:54:21 AM
-
Hi,
I'm supposing that the return address is available on the stack somewhere. How would I return it as a 32-bit integer?
.
.
mov eax, ???
ret
Michael
-
[esp + 8] = second parameter
[esp + 4] = first parameter
[esp] = ???
Return address, of course. Should be 0x804???? or so, for a Linux program...
Best,
Frank
here's a "cute" example that takes advantage of this...
; nasm -f elf32 pfm.asm
; ld -o pfm pfm.o
; "Print Following Message"
global _start
section .text
_start:
call print_following_message
db "Hello Michael!", 10, 0
; how can this work???
mov eax, 1
int 80h
;--------------------------
;--------------------------
print_following_message:
pusha
; initially at [esp], after the pusha
; return adddress is at [esp + 32]
; use it as our buffer
mov ecx, [esp + 32]
xor edx, edx
.getlen:
cmp byte [ecx + edx], 0
; note that if the message *isn't*
; zero-terminated... we're gefukt!
jz .gotlen
inc edx
jmp short .getlen
.gotlen:
mov ebx, 1
mov eax, 4
int 80h
lea eax, [ecx + edx + 1]
; new return address is end-of-string
mov [esp + 32], eax
popa
ret
;----------------------
-
Hi Frank,
This below returns 0x8048600 so I guess I'm in the right neighborhood, but why would it always return the same value, given that it could be called from different places in the code and so (I would think) should return to different places in the code? Am I missing something here?
Michael
global iaddr_
section .text ;return the return addr as a 32-bit integer
iaddr_:
mov eax, [esp]
ret
-
No, that's correct. Is it *not* returning a different return address, depending where it's called from? That seems strange...
I deduce from the trailing underscore that you're calling it from Fortran. Possible that Fortran "consolidates" calls, in some manner??? Seems unlikely. Try it with this caller...
; nasm -f elf32 calliaddr.asm
; ld -o calliaddr calladdr.o iaddr.o
; strip -R.comment calladdr if you like
global _start
extern iaddr_
section .text
_start:
call iaddr_
call showeaxh
times 100h nop
call iaddr_
call showeaxh
mov eax, 1 ;__NR_exit
int 80h
;------------------------------
showeaxh:
push eax
push ebx
push ecx
push edx
sub esp, 10h
mov ecx, esp
xor edx, edx
mov ebx, eax
.top:
rol ebx, 4
mov al, bl
and al, 0Fh
cmp al, 0Ah
sbb al, 69h
das
mov [ecx + edx], al
inc edx
cmp edx, 8
jnz .top
mov byte [ecx + edx], 10 ; linefeed
inc edx
mov ebx, 1
mov eax, 4
int 80h
add esp, 10h
pop edx
pop ecx
pop ebx
pop eax
ret
;------------------------------
That seems to return different numbers, differing by about the expected amount. Haven't actually counted bytes...
(as you can probably tell, I don't "trust" HLLs much - who knows *what* they're doing behind your back? If all else fails, we can disassemble the executable...)
Best,
Frank