0
votes

I have a little program that just adds an item to the stack and then enters a function to add another one. The problem is that it has a weird behaviour every time you execute it.

Here is the function:

.section .data

.section .text

.globl _start
_start:
    # Push
    push $1
    # Function call
    call pfun
    movq $60, %rax
    syscall

.type pfun, @function
pfun:
    # Push
    push $2
    # Return
    ret

Nothing complex at all, but will fail giving a Segmentation fault and if you try to debug it you will find that the error occurs when the program enters inside the function but it will not have any info about where it's located.

Program received signal SIGSEGV, Segmentation fault. 0x0000000000000002 in ?? ()

Now, if you add a "pop" after the function push and run it then it will build and run successfully. BUT if you debug it you will see that it never gets inside the function using the "n"(next) command.

I've searched for an answer but didn't found anything similar at all for ASM. Recently started learning ASM and for me it looks perfectly nice so don't really know why it could be happening.

1
If you consult an instruction set reference you will see that ret pops the top of the stack and uses that as the address to return to. Since you push the value 2 it will try to go there but that is an invalid address. You can see that is printed in the error. You should balance the stack before trying to return. Note that the n command is specifically designed to not step into function calls. Use the s or si commands. See help in gdb. - Jester
Thanks for the help @Jester I see now. Publish it as an answer if you want. - Ricardo

1 Answers

2
votes

Your problem is here:

pfun:
    push $2
    ret

I think you dont understand call/ret correctly. Your function is eqivalent to jmp 2 and that always trigger exception in pm. call is same likepush (r)eip and then jmp and ret is pop (r)eip. In call/function you need to pop everything that you pushed here or add (r)esp,0x??