본문 바로가기
리버싱(Reversing)/리버싱 개념

리버싱 핵심원리 8장(abex' crackme #2)

by LIZ0904 2020. 10. 6.
반응형

abex's 2nd crackme 파일은 Visual Basic(이하 VB)으로 제작되었다. VB 파일은 전용엔진을 사용하는데, 사용 예로는 메세지 박스가 있다. 메세지 박스를 출력하고 싶을 때 VB 소스코드에서 MsgBox() 함수를 사용하는데, VB 컴파일러는 실제로 MSVBVM6o.dll!rtc MsgBox() 함수가 호출되도록 만들고, 이 함수 내부에서 Win32 API 인 user32. dll!MessageBoxW() 함수를 호출해주는 방식으로 동작한다.

 

 

 

 

프로그램 실행

우선 문제에서 주어진 프로그램을 실행하면 위와 같은 화면이 나온다. Name과 Serial에 아무 값이나 넣고 Check를 클릭했더니 'Nope, this serial is wrong!' 이라는 메세지 박스가 나온다. 전형적인 시리얼 값을 찾는 문제로 유추되니, OllyDbg를 이용해 열어보자!

 

 

 

 

메인함수

올리디버거를 실행하면, EP코드는 가장 먼저 VB엔진의 메인함수(ThunRTMain)를 호출한다.

PUSH abexcm2-.00401E14를 통해 스택에 00401E14를 쌓은 후, 아랫줄 CALL <JMP.&MSVBVM60.#100>를 통해 함수를 호출한다. 

 

 

 

함수 호출

하지만 CALL 명령어를 사용해 함수를 호출하게 되면 MSVBVM60.dll!ThunRTMain()으로 바로 가는 것이 아니라 JMP 명령을 통해서 가는 것을 볼 수 있다. (이 과정을 보려면, CALL 함수부분에서 F7키를 눌러 이동해주어야 함) 이게 바로 VC++, VB 컴파일러에서 많이 사용하는 간접호출(Indirect Call)기법이다.

 

 

 

 

ThunRTMain() 함수

JMP를 통해 ThunRTMain() 함수에 오게 됐다. 이는 MSVBVM60.dll 모듈의 주소영역이다. 즉 우리가 분석하는 프로그램의 코드가 아니라 VB 엔진의 코드라는 의미이다. 그렇다면 우리가 패치해야 할 코드는 어디있을까? 다시 올리디버거의 처음 화면으로 돌아가보자! (Ctrl+F2키를 누르면 다시 시작할 수 있음)

 

 

 

 

 

문자열 검색기능

OllyDbg에는 All referenced text strings 라는 문자열 검색기능이 있다. 코드 영역에서 마우스 우클릭->Search for->All referenced text strings를 클릭해준다.

 

 

 

 

문자열 검색기능 결과

그럼 아까 우리가 프로그램을 처음 실행해봤을 때 봤었던 'Wrong serial!!'과 'Nope, this serial is wrong!' 문자열을 볼 수 있다. 더블 클릭을 하면 해당 주소로 이동할 수 있다.

 

 

 

 

해당 주소로 이동

이동하고 나면 위와 같은 화면이 뜰 것이다. wrong 메세지가 뜬다는 것은 어딘가에 성공메세지가 있을 거란 것이고, 이는 어딘가에서 참거짓을 판별한 뒤 맞으면 성공메세지 주소로, 틀리면 wrong 메세지 주소로 이동하게 했을 것이란 추측을 할 수 있다. 때문에 이 코드의 윗부분에는 어딘가 비교코드가 있을 것이다.

 

 

 

 

조건분기 명령어 찾기

아니나 다를까 조금만 위로 올리다보면 조건분기 명령어인 JE를 찾을 수 있다. (참고로 JE는 조건 분기 명령어로, 참/거짓에 따라 다른 주소로 점프시켜주는 명령어임.) 윗줄의 명령어들을 보면, __ vbaVarTstEqO 함수를 호출(CALL)해서 리턴 값을 비교(TEST)한 뒤, JE 명령어가 실행되는 것 같다.

 

 

 

 

JE와 짝꿍인 CALL 함수(734797F6)에 BP를 걸어두고(F2키) 실행한 뒤, Name과 Serial 값을 다시 넣어보자. 

 

 

 

 

레지스터 영역과 스택 영역

이 상태에서 스택을 살펴보면 위의 오른쪽 그림과 같다. 스택에는 0019F290과 0019F2A0이 쌓여있는데, 이는 EAX와 EDX가 갖고 있는 주소와 같다.

 

 

 

 

주소 찾아가기

스택의 가장 윗부분에 쌓여있는 주소(EAX값, 0019F2A0)로 이동해보자. 주소 위에서 마우스 우클릭 -> Follow in Dump를 클릭하면 해당 주소 이동하게 된다.

 

 

 

 

EAX 주소로 이동

스택의 맨 위에 쌓여있고 EAX값이었던 0019F2A0로 가게 되면 표시된 주소로 가게 된다. 내가 입력했던 Name과 Serial이 저장되어 있다.

 

 

 

 

EDX 주소로 이동

스택의 두번째에 쌓여있고 EDX값이었던 0019F290로 가게 되면 표시된 주소로 가게 된다. 처음보는 영문/숫자의 조합이 있다.

 

 

 

 

결국 EDX(0019F290)는 실제 serial 값이고, EAX(0019F2A0)는 내가 입력한 serial 값인거다.  그 후 EDX와 EAX 값을 비교해서 JE 조건분기로 성공/실패여부가 나뉘는 것이다.

 

 

 

 

패치 성공

다시 Crackme 프로그램을 실행해서 위에서 찾은 EDX 주소의 값을 넣어주면, 성공 메세지가 뜨게 된다.

 

 

 

 

길고 긴 풀이 수고하셨습니다....

 

반응형

댓글