본문 바로가기

리버싱/리버싱기초

리버싱 예제 2 (정적분석 vs 동적분석)

1. 파일을 다운받고 압축을 푼다.


파일 : 


리버싱예제2.zip



2. 실행 후 문제가 무엇인지 확인




F1계속 출력 -> F2 계속 출력 -> F3계속 출력하다가 에러!


일단 IDA를 통해 문제가 무엇인지 확인하자.



3. IDA를 사용해 문제 확인


일단 Graph View를 사용해 코드의 진행을 눈으로 확인하자.




일단 어디서 에러가 나는지 모르니 실행을 시켜보자.


메뉴 -> 디버거 -> 스타트 프로세스(F9)


에러창과 함께 다음과 같은 화면을 볼 수 있다.




문제가 무엇인지는 알 수 없으나 몇가지 힌트를 얻을 수 있다.


sub_401020+A 에서 main:loc_401050으로 분기를 하고 잘못된 메모리 영역은 0xA3166을 참조해서 에러가 났다는 것을 알 수 있다.


그렇다면 F3이라는 텍스트를 어디서 참조했는지 알아보자. 아이다는 되돌리기가 없다. 


메뉴 -> 디버거 -> 터미네이트 프로세스



4. IDA 문자열 확인


메뉴 -> 윈도우 -> 스트링 윈도우 (alt + F7) 실행하면 사용되는 스트링을 확인할 수 있다. 하지만...아무리 찾아도 F3은 보이지 않는다. 


마우스 우클릭 -> Setup(Ctrl+u) -> Minimal string length 길이가 5일텐데 이값을 2로 줄이자.




귀찮으니 탭의 String을 눌러서 이름순으로 정렬시킨 후 확인해보니 f3\n이라는 글자가 보인다.





더블클릭 한 후 어디서 참조되는지 확인한다.


DATA XREF: sub_401020... 에 마우스 우클릭 -> jump to cross reference 클릭



단 한 곳에서만 이 문자열을 사용한다.



함수를 쫒아가보니 위와 같은 코드가 존재함을 확인할 수 있었다. 


F3을 출력하는 코드인데.. 이제 이 함수를 어디서 호출하는가 확인하자.


CODE XREF : main+ 19 : 메인코드에서 19바이트 떨어진 위치를 참조하고 있다.


DATA XREF : data + 00406038 : 데이터 섹션으로부터 이만큼 떨어진 위치를 참조하고있다.


CODE:XREF: _main+19... 마우스 우클릭 -> jump to cross reference 클릭


두개의 주소를 볼 수 있으나 하나는 데이터 영역이므로 패스. 코드 부분을 확인해보자.


5. IDA 코드 확인






거의 모든 실마리가 풀렸다. 


call off_406030(edx*4) 는 call [406030+EDX*4] 라는 뜻이다.



edx 가


0일 때 : 406030 : 쫒아가면 F1을 출력하는 함수가 있음

1일 때 : 406034 : 쫒아가면 F2를 출력하는 함수가 있음

2일 때 : 406038 : 쫒아가면 F3을 출력하는 함수가 있음

3일 때 : 406042 : 쫒아가면 0A3166 인데 이 곳에는 함수가 없다.

4일 때 : 406040 : ...


원인은 EDX가 3이상이 되는 코드가 존재하기 때문에 발생한 것이다.


다시 메인코드로 가보면 call off_406030[edx*4]면 호출하면 안되는 것이다.


cmp edx, 3은 


a = edx - 3


if (a > 3)  : jg

   점프 401050

else

   콜 406030[edx*4]


따라서 본 코드는 edx가 3일 때 else 분기로 이동했기 때문에 발생했으므로

jg를 jge로 바꿔주거나 3을 2로바꾸면 이 문제가 해결될 것이다.



6. DeRox 를 사용해 문제 확인


이번에는 DeRox 를 통해 문제가 난 부분을 쫒아가본다.


여기서 trace over 라는 기능을 사용할 것인데 이를 이용하면 문제를 쉽게 확인할 수 있다.


DeRox 를 실행시키고 메뉴 -> 디버그 버튼을 클릭하자. 



step into : 함수를 만날 경우 함수내부로

step over : 함수를 만나면 하나의 코드처럼 넘어감

animate into : 자동으로 실행(어디가 반복문인지 확인하기 위해)

excute till return : 리턴만날 시 스탑

excute till usercode: api돌다가 내 코드만나면 스탑


trace into : 함수 안으로 계속 들어가서 트레이스를 남겨라 

(이 기능은 한계가 있는게 백업할려면 계속 메모리가 필요하므로 레지스터값 계속남기면 너무 방대하다.)


우선 open or clear run trace를 선택해 먼저 쫒아간 trace를 지운다.


trace over를 사용해 에러나는 지점을 확인한다.


실행하면 에러창이 뜰 것이다.


그러면 View -> Run trace 버튼을 클릭해 에러난 지점을 확인하자. 맨 아래로 쭈욱 내리면 


Call Expercise.00401030에서 에러가 났음을 확인할 수 있다.




이제 컨트롤 G를 한후 401030에 브레이크 포인트(F2)를 걸자


리스타트 -> Run -> 401030에서 멈추면


다시 open or clear run trace를 선택해 먼저 쫒아간 trace를 지운다.


또 다시 trace over를 사용해 에러나는 지점을 확인한다.


그리고 또 다시 Run Trace를 확인한다.




확실히 정적 분석 보단 동적 분석을 통해 문제를 쉽게 확인할 수 있었다.




'리버싱 > 리버싱기초' 카테고리의 다른 글

취약점 리버싱 요약 노트  (0) 2020.02.06
DLL(Dynamic-link library) 동적 분석 방법  (2) 2016.03.07
PE파일 데이터 암호화  (0) 2015.10.05
PE파일 구조  (0) 2015.09.23
리버싱 예제 1 (라이센스 우회)  (1) 2015.09.15