[Lenas Reversing for Newbies] 06
1. 프로그램 실행
웬진 모르겠으나 windows xp 32bit 환경을 제외하고는 실행이 안된다...! 어쩔 수 없이 Virtualbox에 windows XP 32bit를 설치한 후 실행해보았다.
잠시 기다리면 다음과 같은 화면으로 넘어간다.
Help 메뉴의 About을 눌러보면 다음과 같은 창을 확인할 수 있다.
고클린과 유사한 기능을 하는 프로그램인 듯하다. Unregistered Version이라 현재 5일 정도 체험을 할 수 있고 이후에는 이용을 못하는 제한이 걸려있는 듯하다. 이번 문제의 목표는 패치를 통해 이 PC Surgeon 프로그램을 등록상태로 크랙 하는 것이다.
2. Debugging(with OllyDbg)
OllyDbg를 이용해 pcsurgeon.exe 프로그램을 연 후, search for all referenced text strings를 이용해 실행화면 2의 Unregistered 문구가 참조되는 곳으로 이동해보자.
이 때, 바로 위의 JNZ 코드에서 만약에 점프를 하게 된다면 "PC Surgeon <unregistered ="라는 문구가 PUSH 되지 않는다. 조금 더 위를 살펴보면 MOV EAX, DWORD PTR DS:[60F1DC]를 통해 60F1DC 주소에 있는 값이 EAX레지스터에 옮겨지고, 다음 CMP BYTE PTR DS:[EAX], 0 명령에 의해 EAX 주소에 있는 값이 0과 같은지 비교하여 그렇지 않은 경우에 문자열 PUSH를 건너뛴다. 그 위의 코드에도 똑같은 방식이지만 60EB8C 주소의 값을 EAX 레지스터에 옮겨 작업을 진행한다. 스크롤을 올려 함수의 시작 지점을 찾아보자.
위의 동그라미 친 부분에서 스택프레임을 생성하는 것을 확인할 수 있다. 해당 지점에 BP를 설정하고 F9를 눌러 프로그램을 실행한 후, 앞에서 언급한 conditional jump 명령 지점까지 F8을 눌러 실행해보자.
앞에서 언급한 부분까지 실행시켰지만 현재 지점에서 점프는 일어나지 않는다. 즉, 현재 EAX 주소 값에는 0이 저장되어 있다. 해당 부분에서 zero flag를 반전시켜 강제로 점프가 되도록 만든 후, F9를 눌러 실행해보자.
위와 같이 점프를 안했을 때와는 달리, 며칠이 남았다는 팝업 윈도우가 초기에 나오지도 않으며, 윈도우 타이틀 바에도 따로 unregistered 문구가 나타나지 않는 것을 확인할 수 있다. Help 메뉴의 About을 눌러 정보를 확인해보자.
이 부분은 아직까지 추가 패치가 필요한 것 같다. 똑같은 방식으로 "<Unregistered Version>" 문자열에 초점을 맞춰 문자열 탐색을 진행하여 참조되는 부분으로 이동해보자.
위와 같이 문자열이 참조되는 부분 바로 위의 conditional jump를 살펴보면 해당 부분에서 점프가 일어나게 되면 "<Unregistered Version>" 문자열을 PUSH 하지 않는다. JNZ 위의 코드를 살펴보면 익숙한 코드가 나타난다.
MOV EAX, DWORD PTR DS:[60EB8C]
CMP BYTE PTR DS:[EAX], 0
아까 전에도 점프 조건에 이용되었던 코드다. 다음 기능을 이용해 60EB8C가 참조되는 곳을 살펴보자.
하나씩 클릭해서 살펴보면 프로그램이 register 되었는지 확인하기 위해 EAX 레지스터에 값을 저장하고, 해당 값을 주소로 하는 곳에 있는 값을 0과 비교하여 0일 경우 unregisterd / 그렇지 않은 경우 registered로 나타내는 흐름을 볼 수 있다. 참조되는 곳 중 첫 번째 부분(처음 패치를 수행했던 곳)으로 이동하여서 코드를 다음과 같이 수정해주자.
EAX 주소값에 0이 아닌 1이 담기도록 수정해준 후, JNZ를 JMP로 수정해주어 Unregistered 문자열을 push 하지 않도록 수정해준다. 이렇게 하면 다음에 참조될 때는 EAX 주소 값에 1이 담겨있으므로 프로그램이 등록된 것으로 인식할 것이다. 이 상태로 패치된 부분을 저장하여 실행하면 아래와 같이 타이틀바와 Help->About 모두 프로그램이 등록된 것으로 인식하는 것을 확인할 수 있다.
3. Comment
해당 프로그램은 Delphi로 작성된 프로그램으로, 일반적인 접했던 프로그램들(Visual C++로 작성된 프로그램)과는 코드 주소 배치와 같은 점에 있어서 다른 점이 느껴졌다. 크랙을 진행하는 데 있어서 단순히 conditional jump를 jump 하도록, 혹은 불필요한 부분을 NOP으로 패치하는 방법도 있지만 곰곰이 생각해보면 unregister로 인식하는 '원인'을 찾아 register로 인식하게끔 바꿔주는 것이 보다 현명한 방법임을 느끼게 해주는 예제였다.