-
printf, scanf등의 호출은 포함하는 함수에서의 push ebx(레지스터)보안/포너블(Pwn) 2021. 7. 2. 15:53반응형
간혹 컴파일된 어셈블리어를 보고 분석하다보면 다음과 같은 상황을 마주하게된다.
- 어떤 함수(func1)에서 분명히 선언한 지역변수는 4바이트 짜리 한개 밖에 없는데, 어셈으로 보면 해당 지역변수의 주소가 ebp-0x04가 아닌, ebp-0x08인 경우.
- 알고보니, 함수 초반에 ebp, esi, edi등이 push된 경우.
참으로 난감한 순간이다.
사실 이는 함수(func1) 호출 전과 후의 레지스터 값을 동일하게 해주려는 백업, 복원잡업이다.
이 작업이 필요한 이유에 대해서는 확언할 수 없다. 추후에 알게된다면 내용을 추가하도록 하겠다.
간단한 예시를 통해 이를 살펴보도록하겠다.
필자는 대표적으로 이 당황스러운 push가 scanf, printf의 호출을 포함하는 경우 발생한다는 것을 발견하였다.
위 함수(scanf, printf)가 호출되는 함수(func1)에서는 push ebx가 함수 코드 초반에 이루어지게 된다.
이를 테스트 해보는 아주 간단한 c코드를 작성해보았다.
#include<stdio.h> void func(){ char *p = "12345"; printf("%s", p); } void main(){ func(); }
gcc -m32 -mpreferred-stack-boundary=2 -z execstack -no-pie -o test3 test3.c
컴파일 후 어셈모습은 다음과 같다.
빨간 박스 3부분에 breakpoint를 걸어주었다. 이제 어떻게 ebx가 변화하는지 알 수 있을 것이다.
실행해보자.
func함수에 막 들어왔을 때 ebx값은 0x0이다.
해당 줄을 실행하면, ebp-0x04부분이 ebx값으로 채워진다.
다음 breakpoint로 가보자. printf의 call 직전, mov ebx, eax부분이다.
mov ebx, eax를 실행하기 직전이다.
이 줄을 실행하면, ebx의 값은 변하게된다.
마지막 breakpoint로 가보자. mov ebx, [ebp-0x04]의 부분이다.
func함수를 종료할 때가 되었다. 이 func의 수행과정에서 수정된 ebx값을 func실행 전의 값으로 돌려놓아야한다.
해당 줄을 실행하면 함수(func)호출 전의 ebx값으로 변화하게된다.
이를 통해 다음 사실을 실험적으로 확인할 수 있었다.
- scanf와 printf의 경우, ebx의 값이 수정될 가능성이 있다.
- 이 가능성에 따라, ebx값을 scanf가 포함된 함수(예제의 func)의 초반에 백업해두고, 프로그램이 종료될 때 복원한다.
또한 이 기능은 mov ebx, [ebp-0x04]로 이루어질 수도 있고, pop ebx로도 이루어질 수 있을 것이라고 생각한다.
참고 : https://bpsecblog.wordpress.com/2016/06/21/re_tutorial_4/
반응형'보안 > 포너블(Pwn)' 카테고리의 다른 글
어셈으로보는 for, while, do-while. (0) 2021.07.02 메모리 보호기법 - SSP(Stack Smashing Protector) (0) 2021.07.02