Author Topic: Where is the return address?  (Read 16568 times)

nobody

  • Guest
Where is the return address?
« 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

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Where is the return address?
« Reply #1 on: January 12, 2009, 05:36:28 AM »
[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
;----------------------

nobody

  • Guest
Re: Where is the return address?
« Reply #2 on: January 12, 2009, 04:32:17 PM »
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

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Where is the return address?
« Reply #3 on: January 12, 2009, 07:51:14 PM »
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