스택 부가 설명
-사진 출처-해커스쿨
스택에 대한 이해를 좀더 하기 위해 간단한 함수를 가져 왔습니다.
1주차때 스터디를 하신분들은 스택이 어떤식으로 쌓이는지 대략적으로 아시게 되셨을거라고 믿습니다.
허나 main()함수에서만 쌓이는 방법은 알고있지만,함수 인자 혹은 다른 함수의 지역변수는 어떻게 쌓이는지에 대해 궁금하실것 입니다.
이것을 설명하기 위한 예제 입니다.
프로그램의 실행 결과 모습 입니다.
메인함수 내에 있는 x와 y는 가장 오른쪽 스택에 자리잡힘을 알수 있고, 그 다음주소에 area의 주소가 잡힘을 알 수 있습니다.
시스템 스택은 cpu를 따라간다고했고, 현재 cpu는 32bit를 기준으로 하기에 모두 4바이트만큼의 크기를 가집니다.
인자 x와 y의 주소값 역시 약간 떨어진곳에 쌓이는것을 확인 할 수 있지만은 모양이 조금 다릅니다.
바로 x부터 쌓인것이 아니라 y부터 쌓인 것 입니다.
그리고 함수내의 지역변수 area의 경우 가장 마지막에 쌓인 것을 확인 할 수 있습니다.
이것을 그림으로 표현하면은 이런식으로 표현이 가능하게 됩니다.
순서 대로 쌓인 모습입니다.
4바이트씩 순서대로 쌓였는데, 함수의 인자모습은 약간 특이 함을 확인 할 수 있습니다.
위의 모습대로 바로 x 와 y가 거꾸로 쌓인것이 아니라 그대로 쌓인것이지요.
좀더 살펴보면은 함수인자가 쌓이고, 그 다음에 get_area 내의 area 변수가 쌓임을 알 수 있습니다.
즉 정리하자면
이런식으로 쌓이게 됨을 알 수 있습니다.
신기한것은 함수인자들과 Get_area()내의 area 함수 사이에 빈공간이 있습니다. 8바이트의 빈 공간이 있는데
이 빈공간에 쌓이는것들이 무엇일까요?
어셈블리의 이해
- 프로그램의 수행과정을 명확히 알 수 있다.
- 메모리에 대한 이해가 깊어진다
- 시스템에 대한 이해도 상승
- 프로그램의 최적화 및 리버스엔지니어링을 하기위해 필요하다.
- 고급 시스템 해킹(bof) 을 수행하기 위해 필요
cpu 레지스터
- 메인메모리, 시스템 메모리외에 cpu의 내부에는 레지스터라 불리는 특별한 메모리
- cpu가 접근할 수 있는 메모리중에서 가장 빠르게 동작하는 메모리
- cpu가 여러가지 연산등의 처리를 하는 동안 필요한 임시적인 데이터들을 보관하는데 사용된다.
EAX : 누산기(acumulator)레지스터라 불리며, 곱셈이나 나눗셈 연산에 사용
EBX : 베이스(BASE) 레지스터라 불리며, 메모리 주소 지정시에 사용
ECX : 계수기(counter)레지스터라 불린다. ex)loop, for...
EDX : 데이터(data)레지스터라 불리고, 곱셈 나눗셈에서 eax와 함께 쓰이며 부호확장 명령등에 사용
32bit -> 2^32 - 42억 edxeax 부족한것을 edx가 앞에 붙어서 도와준다.
ESI : 다량의 메모리를 옮기거나 비교할 때 그 소스의 주소를 가진다.
EDI : 다량의 메모리를 옮기거나 비교할 때 그 목적지의 주소를 가진다.
ESP : 스택 포인터라고 불리고 스택의 가장 윗부분을 가리킨다.
EBP : ESP를 대신해서 스택에 저장된 함수의 파라미터나 지역변수의 주소를 가리키는 용도로 사용된다.
상대주소를 기리킬때 유용하다.
EIP : 다음에 실행될 주소를 가리킨다.
CPU 레지스터중 꼭 확실히 짚고 넘어가야할 중요한 레지스터가 2개 있습니다. 바로 esp와 ebp 입니다.
단순한 구구단 프로그램을 디버그 프로그램인 gdb를 이용해서 디버깅 한것 입니다.
하나하나 상세하게 설명 하도록 하겠습니다.
맨처음 프로그램으로 ebp가 push되고(push %ebp), 그 다음 esp가 ebp의 주소로 잡히게 됩니다.(mov %esp, %ebp)
그 뒤에 8바이트를 esp에서 sub한다는 말은, 주소가 거꾸로 자라는거 다들 아시죠? 즉 8바이트만큼 esp를 뺴줘서 공간을 확보하겠다는거입니다.(sub $0x8, %esp)
그 뒤 and $0xffffffff0와 %esp와 mov 0x0, %eaxx 그리고 sub %eax, %esp는 의미없는 함수 프롤로그 부분 입니다.
여기까지가 함수의 프롤로그라고 불리는 녀석 입니다. 처음 프로그램을 형성할때 형성 되는 과정 입니다.
sub $0x4, %esp -> esp만큼을 4바이트 더 빼준다는 얘기는, 그림과 같이 4바이트만큼을 더 공간확보를 한다는 뜻입니다.
lea 0xfffffff8(%ebp), %eax -> ebp로부터 0x100-0xff = 8 만큼 떨어진곳에 있는 것의 주소값을 복사해서 eax에 넣는다는 뜻 입니다.
즉 8바이트로 선언된 곳에서의 주소값을 가져와서 eax에 넣는다는 뜻 입니다.
push%eax -> 가져온 주소값을 스택에 넣습니다 .esp는 4 만큼 더 커집니다.
leax 0xfffffffc%ebp), %eax -> 같은 방법으로 4만큼 떨어진곳에 있는 것의 주소값을 복사해서 eax에 넣는다는 뜻 입니다.
push%eax -> 가져온 주소값을 스택에 넣습니다 .esp는 4 만큼 더 커집니다.
push $0x8048494 -> x/s 0x8048494를 해보면 저기가 가르키고있는 값을 알 수 있습니다. %d %d가 들어가 있고esp는 4만큼 더 커집니다.
call 0x804827c(scanf) -> scanf함수를 불러오는 부분 입니다. 앞의 인자값들을 이용해서 sacnf 함수를 call 합니다.
add $0x10, %esp -> 잘 보시면은 처음 8바이트 선언된것 말고, 4바이트부터 push 0x8048494까지 총 16바이트를 씀을 알수있습니다
scanf함수를 쓰고, 쓴 만큼 메모리를 정리 해 주는 작업 입니다.
sub $0x8, %esp -> 8바이트만큼을 할당 해 줍니다.
pushl 0xfffffff8(%ebp) -> 위에 설명 했습니다.
psuhl 0xfffffffc(%ebp) -> 위에 설명 했습니다.
call 0x804839c <gugudan> -> gugudan 이라는 함수를 호출 합니다. 인자값은 %d %d scanf 한 값들 입니다.
그 뒤 add $0x10, %esp로 스택을 정리 해 줍니다.
leave
ret
에필로그 부분 입니다.
'CAT-Security > 미분류' 카테고리의 다른 글
sdfsdf (0) | 2012.11.13 |
---|---|
리눅스 아파치 서버 설치 (0) | 2012.11.13 |
gdb 잘나와있음 (2) | 2012.11.09 |
[시스템 기초] 스터디(1주차) (0) | 2012.11.08 |
[안티디버깅] UPX packer 이해 (0) | 2012.11.08 |