Why is this NASM code printing environment variables?

I'm just finishing my computer architecture course this semester, where, by the way, we were building MIPS and running it in the MARS simulator. Today, out of curiosity, I started tinkering with NASM in my Ubuntu box and basically just collecting stuff from the tutorials and feeling how NASM is different from MIPS. Here's the piece of code I'm currently looking at:

global _start

_start:

    mov eax, 4
    mov ebx, 1
    pop ecx
    pop ecx
    pop ecx
    mov edx, 200
    int 0x80
    mov eax, 1
    mov ebx, 0
    int 0x80

      

This is saved as test.asm and is compiled with nasm -f elf test.asm

and linked to ld -o test test.o

. When I call it with ./test anArgument

, it prints "anArgument" as expected, followed by as many characters as I want to fill that line up to 200 characters (because of this operator mov edx, 200

). Interestingly, however, these uppercase characters, which I expected to be gibberish, are actually from the very beginning of my environment variables as shown by the command env

. Why is this printing my environment variables?

+1


source to share


3 answers


Not knowing the actual answer, or the time to find it, I am assuming that the environment variables are getting in memory after the command line arguments. Your code just buffer overflows into environment variable strings and prints them too.

This really makes sense since command line arguments are handled by the system / loader as well as environment variables, so it makes sense that they are stored next to each other. To fix this, you will need to find the length of the command line arguments and only print a lot of characters. Or, since I am assuming they are null terminated strings, print until you reach a null byte.



EDIT: I am assuming that both command line arguments and environment variables are stored in the initialized data section (e.g. in NASM).

+6


source


To understand why you are getting environment variables, you need to understand how the kernel arranges memory when a process starts. Here is a good explanation with a picture (scroll down to Stack Layout).



+3


source


As long as you're curious, you can work out how to print the address of your string (I think it went through and you popped it off the stack). Also, write a hex dump routine so you can look at this memory and any other addresses you are interested in. It can help you learn about the programming space.

Curiosity may be the most important thing in a programmer's toolbox.

I haven't researched the specifics of the initial processes, but I think that every time a new shell is started, a copy of the environment is created for it. You can see the remnants of the shell that was started by the command you ran, or the script you wrote, etc.

+1


source







All Articles