What is on the stack before the start of my program?

I am learning a high-level assembly language at the moment, and I play with glass to better understand everything.

I note that in the next program, I can pull the contents of the stack without clicking anything 37 times before the program crashes.

ike1: uns32 := 1; begin test1; while (ike1 < 38) do pop(eax); stdout.put(ike1, nl); stdout.put("ESP: ", esp, nl); stdout.put("EAX:", eax, nl, nl); add(1, ike1); endwhile; end test1; 

Each time the stack is popped into EAX and the output from EAX is randomly displayed every time.

Firstly, I do not understand how this is possible, since I thought that each program was divided into its own memory space?

In any case, I push the data from the stack ... what would it be and would affect any other running programs?

My OS is a 64-bit version of Windows 7.

+6
source share
2 answers

Before executing main() operating system must perform a bunch of other operations to properly configure the environment before execution control is processed by your application. Thus, most of what is currently on the stack is garbage left over from previous operations.

Before executing main() you can find argc and argv on the stack.

EDIT:

The kinda user comment made me go through the debugging process of the build application in gdb and examine the stack to back up the statement I made in the original answer.

Therefore, please consider the following assembly code written in nasm:

 section .data mymsg db "hello, world", 0xa ; string with a carriage-return mylen equ $-mymsg ; string length in bytes section .text global mystart ; make the main function externally visible mystart: ; prepare the arguments for syscall write() push dword mylen ; msg length push dword mymsg ; msg to write push dword 1 ; file descriptor number ; call write() mov eax, 0x4 ; 0x4 identifies syscall write() sub esp, 4 ; OS X (and BSD) syscalls needs "extra space" on stack int 0x80 ; trigger the call ; clean up the stack add esp, 16 ; 3 args * 4 bytes/arg + 4 bytes extra space = 16 bytes ; prepare argument for syscall exit() push dword 0 ; exit status returned to the operating system ; call exit() mov eax, 0x1 ; 0x1 identifies syscall exit() sub esp, 4 ; OS X (and BSD) system calls needs "extra space" on stack int 0x80 ; trigger the call 

I compiled this on Mac OS X using

 nasm -f macho -o hello.o hello.nasm ld -o hello -e mystart hello.o 

As you can probably tell from the source code, the start of the application is determined by mystart , and it does not accept any parameters.

Now let's make this study more interesting by opening this program in gdb :

 gdb ./hello 

After downloading gdb for educational purposes, it is important to set the cmd line parameter for this application, even if it was not written to accept any.

 set args deadbeef 

At the moment, the application is still not working. We need to set a breakpoint at the beginning of the main function so that we can check the stack to find out what happens before our application starts to execute its own code:

 break mystart 

Run the run command on gdb to start the application and abort. Now we can check the stack with

 x/20xw $esp 

outputs:

 (gdb) x/20xw $esp 0xbffff8cc: 0x00002000 0x00000000 0x00000002 0xbffff96c 0xbffff8dc: 0xbffff98b 0x00000000 0xbffff994 0xbffff9b0 0xbffff8ec: 0xbffff9c1 0xbffff9d1 0xbffffa0b 0xbffffa40 0xbffff8fc: 0xbffffa5b 0xbffffa86 0xbffffa97 0xbffffaad 0xbffff90c: 0xbffffad8 0xbffffafa 0xbffffb06 0xbffffb28 

Yes sir, this command prints the contents of the stack. It tells gdb to show 20 words in hexadecimal, starting with the address stored in the $esp register.

Let's see that $esp actually points to 0xbffff8cc , fine, but when analyzing what is stored at this memory address, another address is displayed: 0x00002000 . What does this indicate?

 (gdb) x/20sw 0x00002000 0x2000 <mymsg>: "hello, world\n" 

Not a shocker, right ?! So let's see what some other table addresses point to:

 (gdb) x/1sw 0xbffff96c 0xbffff96c: "/Developer/workspace/asm/hello" 

Wow. This is truly an original name and path app stored right on the stack! Surprisingly, let me continue with the following interesting table address:

 (gdb) x/1sw 0xbffff98b 0xbffff98b: "deadbeef" 

Jackpot! The cmd argument that we passed when running our application was also saved on the stack. As I said earlier, among the garbage stored on the stack, before executing your application, you can also find the cmd line parameters that were used to execute the application, even if the main() function of the application is void and doesn't accept any parameters.

+3
source

The private memory space allocated to your program cannot be cleared (i.e. 0x0000). Access to unallocated memory is usually undefined, which explains the random data you receive.

+1
source

Source: https://habr.com/ru/post/895773/


All Articles