티스토리 뷰

안녕하세요!

 

이번 시간에는 지난 시간에 작성한 프로그램을 gdb를 사용하여 분석해보는 시간을 가질거에요.

 

gdb는 리버싱을 하는 데 있어서 매우 중요합니다. gdb를 다루지 못한다는 것은 리버싱을 할 수 없다는 것과 같은 이야기입니다.

 

 

지난 시간에 작성한 프로그램을 gdb를 사용하여 분석해볼게요.

 

'gdb XXX' 를 입력하시면 (gdb) 옆에 명령어를 입력할 수 있게 바뀌게 됩니다.

 

1. disassemble (disas)

 작성한 코드가 어셈블리 코드로 출력됩니다.

 

 

 지금 어셈블리 코드를 보면 AT&T 방식으로 표현되어 있는데 우리는 앞으로 intel 방식으로 볼거에요.

 

 따라서 다음과 같은 명령어를 입력해주세요.

 

 set disassembly-flavor intel

 

 

2. info register

 이 명령어는 레지스터의 정보를 볼 수 있는 명령어 입니다. 레지스터는 프로그램이 실행되고 있는 상태에서 확인할 수 있기 때문에 프로그램을 run 명령어를 입력하여 실행합니다.

 

 

 하지만 지금 상태에서 프로그램을 실행시키면 바로 끝나게 되고 지난 시간에 발생한 Segmentation fault가 뜨게 됩니다.

 이렇게 되면 우리가 이 프로그램을 분석을 할 수 없잖아요?? 그래서 사용하는 것이 break point 입니다.

 

3. break point (b)

 

 

저는 break point를 main에 걸었습니다.

 

0x8048060에 break가 걸렸다는 것을 알 수 있습니다.

 

0x8048060을 보시면 main의 첫 번째 명령어에 break가 걸렸다는 것을 알 수 있습니다.

 

이제 다시 프로그램을 run 해주면 지정해놓은 break point에 걸리게 됩니다.

 

 

프로그램을 실행시켜보면 main의 0x08048060에서 break point에 걸렸다는 메시지가 출력되는 것을 확인할 수 있습니다.

 

이 때 main을 disas 해보면 화살표 표시로 이 프로그램의 문맥이 이곳에 도달했다는 것을 표시해줍니다. 즉 이 명령어를 시작하기 전이다라는 것을 의미합니다.

 

이제 레지스터 값들을 확인해볼 수 있습니다.

 

 

레지스터 정보를 보면 다른 곳에는 모두 0이 들어가 있는데 esp와 eip만 값이 들어가 있는 것을 확인할 수 있습니다.

 

eip는 다음에 실행할 명령어를 가리킵니다. 현재 0x8048060이 들어가 있는데, 이는 break point를 걸어놓은 지점입니다.

 

위에서 설명했듯이 break point 지점은 아직 실행되지 않은 명령어입니다.

 

esp는 0xbffff160 을 가지고 있습니다. 이 값의 의미는 스택의 사용자 영역에 들어와 있다는 것을 의미합니다.

 

각각의 레지스터 정보를 보고싶다면 'info reg $xxx'를 입력해주시면 됩니다.

 

 

 

자 지금부터는 PUSH 명령어와 POP 명령어에 의해 esp의 값이 어떻게 변하는지 확인해보도록 하겠습니다.

 

 

ni 명령어를 사용하여 하나의 명령어를 실행해봤습니다.

 

disas main의 결과를 보면 화살표가 0x08048062를 가리키고 있습니다.

 

즉 현 상태는 0x08048060의 명령어를 실행한 뒤에 멈춘 상태 입니다.

 

이 때 esp에 어떤 값이 들어있는지 확인해보니, 0xbffff15c가 들어있었습니다.

 

이전에 들어 있던 값에서 4바이트가 감소한 값이네요! 즉 현재 스택이 4바이트 밑을 가리키고 있습니다.

 

또한 저 스택의 위치에 어떤 값이 들어있는지 확인해볼 수도 있습니다.

 

 

스택의 0xbffff15c 위치에 0x00000010이 들어있다는 것을 확인해봤습니다.

 

(x/x는 data를 보겠다는 것이고, x/s는 string, x/i는 instruction을 출력하겠다는 의미입니다.)

 

ni 명령어를 사용해서 계속 분석해보겠습니다.

 

 

이번에는 스택의 0x08048062 위치의 push 명령어를 실행한 뒤에 멈춘 상태입니다.

 

이 때 esp의 값을 확인해보니 이전의 값에서 4바이트 감소된 0xbffff158이 들어있습니다.

 

 

스택의 0x08048067 위치의 pop 명령어를 실행한 뒤에 멈춘 상태입니다.

 

이 때 esp의 값에는 이전의 값보다 4바이트 증가된 0xbffff15c가 들어있습니다.

 

pop은 스택에서 값을 꺼내와서 레지스터에 넣는다고 설명을 했었습니다.

 

그럼 eax에 0x12345678의 값이 제대로 들어있는지 확인해보겠습니다.

 

 

레지스터 eax를 확인해보니 0x12345678이 있는 것을 확인할 수 있습니다.

 

그럼 다음 명령어 pop에서 ebx에 어떤 값이 들어갈 것인지 예측이 가능하신가요??

 

바로 확인을 해보겠습니다.

 

 

자 여러분들이 예측하신 값과 일치하나요??

 

pop 명령어를 실행했으므로 esp에는 이전의 esp 값보다 4바이트 증가한 0xbffff160이 들어있고, ebx에는 0x10이 들어있습니다.

 

?? 에러는 0x08048069의 주소가 무엇인지 모르겠다는 에러입니다.

 

우리가 이 프로그램을 작성할 때 push와 pop만 해주었을 뿐이지 프로그램이 종료되었다는 신호를 주지 않았습니다.

 

eip는 자동으로 다음에 실행할 명령어를 찾게되는데, 다음 명령어가 해석할 수 없는 이상한 명령어일 경우에는 ??과 같이 에러가 발생하게 됩니다.

 

정리하자면 이번 시간에는 push와 pop을 했을 때 스택 포인터가 어떻게 변화하고 pop을 했을 때 레지스터에 어떻게 들어가는지 gdb를 사용해서 확인해봤습니다.

 

처음에 말씀드렸듯이 gdb 사용법은 손에 꼭 익혀야 합니다.

 

인터넷에서 gdb 레퍼런스들을 찾아보시고 직접 실습을 진행해보시는 것을 권장드립니다!

 

다음 시간부터는 각종 명령어에 대해서 알아보겠습니다! ^^

 

 

 

 

 

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함