본문 바로가기

High Level Technique/System Hacking

main의 SFP는 왜 0이 되는가?

main의 SFP는 왜 0이 되는가?






목적


main함수 외 프로그래머가 만든 함수에 진입 시 ebp의 값을 저장하기 위해 SFP 공간에 ebp를 저장되는 것을 알 수 있다.

하지만 main함수 또한 libc_start_main에서 넘어와 main함수가 시작 되는데, 그러면 main의 SFP에도 libc_start_main에서 사용된 ebp가 저장되어야 하지 않을까?

라는 의문이 든다.


왜 main함수에서의 SFP의 값이 0이 되는지에 대해 분석해 보았다.








탐구





위와 같이 아주 간단한 C 코드를 작성하여 -fno-stack-protector -mpreferred-stack-boundary=2 옵션을 사용하여 컴파일 후  gdb로 분석을 합니다.


gdb를 이용하여 실행 되기 전 i func 명령어를 통해서 함수들을 확인 합니다.







프로그램이 실행될 때 _start부터 시작합니다.


http://dbp-consulting.com/tutorials/debugging/linuxProgramStartup.html


위 사이트를 들어가면 되게 복잡한 과정을 통하는데 너무 깊게 볼 필요는 없다고 생각해서 _start 부분에 브레이크 포인트를 걸고 어떤 과정을 통해서 main함수에 도달하는지 알아 보도록 하겠습니다.



_start





ebp의 값을 xor 연산을 통해서 0으로 만들고 있습니다. 애초에 ebp에 값이 들어있었다면 초기화 시키고 사용하려고 하는 것 같습니다. 그럴리도 없겠지만..


여러과정을 수행하지만 ebp에 대해서 명령을 수행하는 부분은 찾을 수 없습니다. 굳이 ebp와 연관되어 사용되는 esp에 대해서 보더라도 지금까지 esp 값은 esp에 대해서만 사용되지 ebp와 연관되어 사용되는 부분은 나타나지 않았습니다.





_libc_start_main@plt





libc_start_main 부분에 들어와서 해당 부분의 어셈블리어를 확인하면 위와 같이 나오게 됩니다.

첫 번째 jmp문에서 0x804a010에 있는 값으로 점프를 수행하는데 해당 값은 다음 주소인 0x8048326이여서 그냥 다음 줄을 실행하게 됩니다.


0x8 값을 스택에 저장하고 두 번째 점프문인 0x8048300으로 점프를 하게 됩니다.


해당 부분으로 점프 후 disas 명령어를 사용하면 해당 부분의 어셈블리어 코드를 확인 할 수 없었습니다.


그래도 peda를 이용하여 실행되고 있는 부분을 확인 할 수 있습니다.




0x804a004에 있는 값을 스택에 저장하고 0x804a008 위치로 점프를 하게 됩니다.


해당 주소로 점프를 하면 아래와 같은 위치로 이동하게 됩니다.



_dl_runtime_resolve





여기서도 ebp와 관련된 명령을 수행하는 곳이 나타나지 않았습니다.

중간에 call 명령을 하는 부분에 들어가보도록 하겠습니다.









_dl_fixup





해당 위치에서는 push ebp를 하는 것을 볼 수 있고, mov ebp, esp 또한 하는 것을 볼 수 있습니다.


함수의 프롤로그를 나타내고 있죠. 해당 두 줄을 수행 후 ebp와 esp를 확인해 보도록 하겠습니다.




_dl_fixup에서 사용된 ebp의 값인 0x0을 push 명령을 통해서 스택에 쌓아뒀습니다. 분명이 값도 다시 사용하기 위해서 저장을 해두는 것일겁니다.

다시 _dl_fixup로 돌아왔을 때 ebp를 사용하기 위해서? 라고 생각합니다.


그리고 0xb7fec0ae에서 __x86.get_pc_thunk.bx 를 call하는 것을 알 수 있습니다.


해당 부분으로 들어가 보도록 하겠습니다.




esp에 있는 값을 ebx에 넣고 ret을 수행하는 것을 알 수 있습니다. ret는 pop eip jmp eip 이므로 esp에 있는 값으로 이동을 하게 될 것입니다.




다시 dl_fixup으로 이동한 것을 볼 수 있습니다.


call하는 부분들은 결국 다시 원래 있던 곳으로 돌아 올테니 넘어가도록 하겠습니다.






중간 쯤 보면 ret를 하는 곳이 나타납니다. 일단 해당 주소에 브레이크 포인트를 걸고 어디로 이동하는지 확인해 보겠습니다.


해당 위치까지 온 후 스택을 확인해 보면 아래와 같습니다.




0xb7ff2500으로 넘어가겠네요.





해당 주소는 _dl_runtime_resolve였습니다. 지금까지 눈여겨볼 ebp또한 0으로 유지되고 있죠.


그리고 몇개의 어셈을 수행 후에 ret를 하고 있는것을 알 수 있습니다.


해당 위치에 브레이크 포인트를 걸고 스택을 확인하여 어디로 넘어가는지 확인해보면 아래와 같습니다.






__libc_start_main


 

해당 위치로 이동한 결과 __libc_start_main으로 이동했습니다.


마찬가지로 중간에 call하는 부분들이 많이 있는데, 마찬가지로 그냥 넘어가겠습니다. 


어... 중간에 넘기다가 그냥 실행? 되버렸네요.. 하하하







여튼 이게 ebp가 왜 0이 되는가? 에 대한 답은


1. _start에서 ebp에 대한 xor 명령을 수행한다.

2. 다른 곳에서 ebp를 사용하지 않는다.



결론. 그냥 0이다.



'High Level Technique > System Hacking' 카테고리의 다른 글

Return To Library (RTL)  (2) 2016.04.20
Plt 와 Got  (0) 2016.04.20
Fake EBP  (0) 2016.04.19
Save Frame Pointer Overwrite (SFO)  (0) 2016.04.15
Buffer Over Flow (BOF)  (5) 2016.04.15