먼저 gdb를 통해 stack0 을 메인함수까지 디스어셈블을 해보았다.

다음과 같은 프로그램의 C 소스코드는 다음과 같다.
#include <stdlib.h>#include <unistd.h>#include <stdio.h>int main(int argc, char **argv)
{
volatile int modified;
char buffer[64];
modified = 0;
gets(buffer);
if(modified != 0) {
printf("you have changed the 'modified' variable\\n");
} else {
printf("Try again?\\n");
}
}
위에 코드를 해석해보자면
64바이트의 크기로 변수 buffer을 선언하고 4바이트 크기의 modified 변수 또한 선언한다.
if문을 통해 modified 변수가 0인지 아닌지 확인해 Success 혹은 Failed를 타나내게 출력한다.
어셈블리어 부분 또한 해석을 해보자.
0x080483f4 <+0>: push ebp
0x080483f5 <+1>: mov ebp,esp
0x080483f7 <+3>: and esp,0xfffffff0
0x080483fa <+6>: sub esp,0x60
0x080483fd <+9>: mov DWORD PTR [esp+0x5c],0x0
0x08048405 <+17>: lea eax,[esp+0x1c]
0x08048409 <+21>: mov DWORD PTR [esp],eax
0x0804840c <+24>: call 0x804830c <gets@plt>
0x08048411 <+29>: mov eax,DWORD PTR [esp+0x5c]
0x08048415 <+33>: test eax,eax
0x08048417 <+35>: je 0x8048427 <main+51>
0x08048419 <+37>: mov DWORD PTR [esp],0x8048500
0x08048420 <+44>: call 0x804832c <puts@plt>
0x08048425 <+49>: jmp 0x8048433 <main+63>
0x08048427 <+51>: mov DWORD PTR [esp],0x8048529
0x0804842e <+58>: call 0x804832c <puts@plt>
0x08048433 <+63>: leave
0x08048434 <+64>: ret
1행 ~ 3행 까지는 함수 프롤로그로 스택구조의 최하위를 가리키기 위해 존재하는 어셈블리어다.
Push ebp는 ebp를 스택에 저장하는 걸 뜻하며 mov ebp, esp 는 현재 esp 위치에 ebp를 끌어올리는 명령어다.
0x080483fa <+6>: sub esp,0x60
부분에서 esp 레지스터에 main 함수가 사용할 0x60 크기 만큼 공간을 할당한다.
0x080483fd <+9>: mov DWORD PTR [esp+0x5c],0x0
esp+0x5c에 주소를 0으로 지정한다.

변수에 0을 지정하는 것은 modified 변수 밖에 없으므로 esp+0x5c는 modified 변수의 주소인 것을 확인할 수 있다.
그 밖에 DWORD는 데이터의 크기를 나타내므로 4바이트를 의미한다. (( 그 외에는 WORD =2byte BYTE = 1byte 가 있다.
0x08048405 <+17>: lea eax,[esp+0x1c]
0x08048409 <+21>: mov DWORD PTR [esp],eax
0x0804840c <+24>: call 0x804830c <gets@plt>