본문 바로가기
리버싱

리버싱 기초- 간단한 C코드로 코드분석

by 웹하는빡통 2020. 4. 17.

여기 아주 매우 그것도 엄청 실눈떠도 무슨 코드인지 아는 유아 수준의 간단한 코드가 있다. 보통 사람이 해석하기 편한 언어를 High Level Language라고 부른다. 

 

disas를 이용하여 main()를 disassemble하였다. 여기서 코드하나하나가 어떻게 동작하는지 살펴보자.

먼저 rbp값을 push해준다 그 다음 mov로 rsp값과 rbp값을 같게 해준다. 여기서 rsp가 시작지점이다. 

 

그 다음 sub를 이용하여  0x10 만큼의 크기를 뺴준다. 그리고 16byte 공간에 C에서 선언한 변수들이 들어간다. 

 

그 다음 0x5를 [rbp-0x4]만큼 떨어진 곳에 4byte 크기로 넣어준다 여기서 DWORD는 4byte이다.

똑같이 0xa를 [rbp-0x8]만큼 떨어진 곳에 4byt 크기로 넣어준다. C코드에서 5와10의 값을 의미한다.  

 

[rbp-0x4]와 [rbp-0x8]에는 5와 10의 값이 들어가있다. 그 다음 edx와 eax에 해당 값을 넣어주고 add로 이용하여 더 해준다. edx(5) -->eax(10)에 값을 더하여 eax값이 15가된다.

 

그 다음 eax를 [rbp-0xc]만큼 떨어진 곳에 값을 넣어주는데 C코드에서 c=a+b;부분이 된다. 

 

그 다음 eax를 edi에 넣어주는데 edi는 데이터를 복사할때 목적지 주소가 저장되는 명령어로 C코드로는 loopfuntion(c)에 해당한다. 해당 함수안에 들어 있는 c값을 전달하기 위해 eax를 edi에 넣어준것이다. 그 다음 call을 이용하여 함수를 호출 한다. 

자 여기까지가 main함수를 disassembly 한 것이다 이제 loopfuntion()로 가보자. 

 

 

자 여기서부터 loopfuntion함수 부분이다. 하나씩 살펴보자.  

 

여기 edi를 [rbp-0x14]만큼 떨어진 곳에 edi의 값을 넣었다. 여기서 edi는 loopfuntion(int d)에 해당 하는 부분이다. 

 

cmp로 [rbp-0x14]와 0xf를 비교하고 있다. rbp-0x14에는 정수 15값이 들어있다. 그런데 바로 아래에 jne라고 있다.

jne는 jump not equal이라는 뜻으로 cmp에서 비교한 값이 같지 않다면 jne가 가리키는 오퍼랜드 주소로 점프를 하라는 의미이다. 이부분은 C코드에서 if(d ==15)에 해당한다. 

 

그리고 해당 어셈블리 코드가 C코드의 for문 즉 반복문에 해당한다. 하나씩 천천히 살펴보자. 

 

먼저 0x0을 [rbp-0x4]에 넣어준는데 C코드에서 i=0;에 해당하는 부분이다.  

 

그 바로아래 jmp로 0x1164에 해당하는 주소로 점프를 시키는데

여기서 cmp로 아까 0이 할당된 [rbp-0x4]와 0x2값을 비교하고 있다. jle는 jump less or equal로 값이 작거나 같으면 0x114f 주소로 점프를 시킨다. 즉 쉽게 말해 cmp 해당 하는 0x2를 포함한 값이 작거나 같으면 0x114f로 점프를 하게된다. 만약  값이 3이라면 그대로 아래로 진행한다. C코드에서 i<3;에 해당하는 부분이다. 

 

아직은 [rbp-0x4]의 값이 0이니 lea로 점프를 하고 있다 그 다음 아래 call명령어로 함수를 호출하고 있는데. 바로 printf()를 호출하고 있다. C코드에서 printf("i hate reverse");에 해당 한다. 

 

그리고 add에 0x1를 [rbp-0x4]에 더해준다. 아까 [rbp-0x4]가 0이였으니 1을 더해 값이 1이되고

또 cmp로 내려가서 [rbp-0x4]와 0x2값을 비교하고 jle를 통해 해당 주소로 점프를 한다.

이렇게 i가 3이 될때까지 반복하고 3이되면 반복문을 빠져 나간다. 

C코드에서 I++에 해당한다.

 

자 이렇게 반복문을 빠져나가 leave를 통해 스택프레임을 정리하고 ret로 아까 call함수를 불러왔던 다음 명령줄로 이동을 하라는 의미이다.  

 

ret로 이동을 한 부분이 맨 처음 main 함수의 이 부분이다. 즉 C코드에서 return 0;을 의미하는데

eax는 값을 연산할때 사용도 하지만 return값도 받는다.   

 

지금까지 어셈블리로 간단하게 짠 C코드르 분석해 봤다 C코드를 봤을땐 유아 수준의 코드였다하지만 어셈블리로 해당 C코드를 분석해보니 조금 복잡하다. 실제 악성코드 분석이나 리버싱을 할때는 이 보다 더 복잡하고 어려운 코드를 분석한다. 기초 부터 차근차근 본인이 직접 C코드로 아무거나 만들어서 그걸 어셈블리로 분석하는 훈련을 기르도록 하자. 필자도 리버싱을 처음 하는거라 많이 어렵다.... 

'리버싱' 카테고리의 다른 글

pwnable-Bof write up  (1) 2020.04.16

댓글