본문 바로가기

CAT-Security/미분류

[시스템 기초] 스터디(2주차)


스택 부가 설명

-사진 출처-해커스쿨


스택에 대한 이해를 좀더 하기 위해 간단한 함수를 가져 왔습니다.

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 입니다.


ESP (Extended Stack Pointer)
현재 스택의 가장 위에 들어있는 데이터를 가리키고 있는 포인터
-  Intel CPU에서는 스택이 거꾸로(리틀엔디언자라므로 데이터가 하나 PUSH 될때마다 ESP 값은 감소

EBP (Extended Base Pointer)
- 현재 스택에 가장 바닥을 가리키는 포인터
- 새로운 함수가 호출될 때마다 EBP 레지스터 값이 지금까지 사용했던 스택 꼭대기의 위에 위치하게 되고 새로운 Stack이 시작
따라서 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