Question


According to this paper and a few stackoverflow posts, argc is at the top of the stack and argv is below it. I've tried about 3-4 different ways of doing it:

  • Popping it into an initialized variable (.data) - output done by calling printf.
  • Popping it into uninitialized space (.bss) - output done by calling sys_write()
  • A mixture of the above + tweaks.

I've been told that argc and argv aren't in the stack by someone on a forum, which I don't understand; how are other people doing it with similar code?

Here's an example of what I've attempted (3 days worth of knowledge - try not to giggle):

section .bss
        argc:   resd 1      ; alloc 4 bytes for popped value

section .text
        global _start


_start:
        pop   dword[argc]   ; pop argc, place in var
        mov   ebx,0x01      ; file descriptor = STDOUT
        mov   ecx,argc      ; var (addr) - points to buffer
        mov   edx,1         ; length of buffer (single digit)
        mov   eax,0x04      ; syscall number for sys_write()
        int   0x80          ; request the kernel to make syscall

exit:
        mov   ebx,0x00      ; arg for sys_exit() - sys_exit(0)
        mov   eax,0x01      ; syscall number for sys_exit()
        int   0x80          ; request the kernel to make syscall

Solution: section .data msg db Value: %d\n

section .text
        global main
        extern printf

main:
        push   dword[esp+4]
        push   msg
        call   printf
        add    esp,8

        mov    eax,0
        ret
Was it helpful?

Solution

The process of getting argc looks ok to me (for a 32-bit Linux machine), although you're 4 bytes off since the top of the stack most likely contains the return address to the startup code that called main.
Also, the sys_write system call expects a pointer to a string in ecx. What you're giving it is a pointer to an integer, which isn't the same thing.
If you want to print the value of argc you'll have to convert it to a string first (or use the printf function).

Here's some example code (I'm using the GNU assembler since I don't have NASM on this machine):

format: .asciz "%d\n"
.text
.globl main
  .type main, @function
main:
  pushl 4(%esp)       # push argc
  pushl $format       # push the format string
  call printf
  addl $8,%esp        # pop the arguments

  movl  $0, %eax      # return value 
  ret
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top