[Lenas Reversing for Newbies] 12
1. 프로그램 실행
첨부된 Teksched.exe를 실행해보자.
위와 같이 unregistered 버전임을 확인할 수 있다. Help->About을 클릭하여 정보를 확인해보자.
아래의 Use Reg Key 버튼을 클릭하면 다음과 같이 키 등록을 할 수 있는 창이 나타난다.
임의의 키를 입력했을 때 등록이 되도록 크랙 하는 것이 이번 문제의 목표다.
2. Debugging(with OllyDbg)
OllyDbg로 Teksched.exe 파일을 열고 search for referenced string을 이용해 참조되는 문자열을 검색해보자. 성공적으로 등록되었을 때 registration이라는 키워드가 포함되었을 것이라는 가정하에 registration 문자열을 검색해보면 다음과 같은 문자열이 참조되는 것을 확인할 수 있다.
인증에 성공했을 때 나타나는 문자열인 것 같다. 해당 부분으로 이동해보자.
004A584B의 명령어를 통해 문자열의 주소가 EAX 레지스터에 옮겨진다. 이때 위의 파란 화살표 표시를 주목해서 보면 push 명령 이후에 retn 명령이 나타나는데 이는 push 했던 argument의 주소로 점프하는 기능과 같음을 알 수 있다.
push target + retn == jmp target
push 명령어가 나타나는 004A582C를 기준으로 더 위에 있는 코드를 살펴보자.
004A55F9에 무언가 등록이 잘못되었을 때 나타날법한 문자열이 옮겨지는 것을 확인할 수 있다. 004A55F3 명령어에서 점프가 이뤄져야 할 것 같다. 계속해서 위쪽의 코드를 살펴보자.
"Enter..." 문자열이 나타난다. 키를 등록할 때 프로그램에서 First Name, Last Name, Registration Key를 요구하는데, 누락된 것이 있을 때 참조되는 문자열인 것 같다. 004A53E8에 BP를 설정하고, 프로그램을 실행한 후 임의로 키 등록을 시도해보자.
Register 버튼을 누르면 BP에 적중한다.
이때 다시 F9를 누르면 다음과 같은 에러 메시지가 나타난다.
다시 키 등록을 시도한 후, BP 지점부터 F8을 누르며 어떤 지점에서 문제가 발생하는지 확인해보자.
디버깅을 진행하다 보면 체크 표시한 004A5461지점에서 ntdll 모듈로 넘어가는 것을 확인할 수 있다. 임시방편으로 해당 부분을 NOP으로 변경한 후, 위의 명령어에 BP를 설정한 후 다시 키 등록을 시도해보면 아래와 같이 문제없이 넘어 가는 것을 확인할 수 있다.
이제 다시 디버깅을 진행해보자. 004A5479 주소에 JBE라는 conditional jump 명령어가 보인다. 일단 F9를 눌러 어떤 결과가 나타나는지 확인해보자.
이 문자열은 아까 디버깅을 진행하면서 보았던 오류 메시지 문자열로, OllyDbg에서 스크롤을 조금 내리면 확인할 수 있다.
004A55ED에 BP를 설정하고 다시 키 등록을 시도하면 해당 지점에 BP가 적중하며, 점프가 안 일어나는 것을 확인할 수 있다. zero flag를 반전시켜 강제로 점프가 일어나게 해 보자.
그러자 이번에는 "Registration Key Failed!"라는 메시지 박스가 출력된다. 밑에 있는 코드를 살펴보니 다음과 같은 명령어가 보인다.
해당 지점에서 점프가 일어나지 않으며 위와 같은 메시지 박스가 출력되는 것이다. 앞선 작업들과 마찬가지로 임시로 zero flag를 반전시켜서 실행해보았지만 인증 성공 문구가 출력되지 않고 그대로 인증과정이 종료된다. 무언가 위에 있는 코드의 수정이 필요한 듯하다. 바로 위의 CMP BYTE PTR SS:[EBP+8], 0 명령어를 보면 004A5672에서 점프가 일어나는 것을 알 수 있고 해당 지점에서 zero flag를 반전시키면 다음과 같이 인증에 성공한다.
크랙을 위해 총 두 군데에서 zero flag를 반전시켰다.
004A55ED JE SHORT 004A5608 -> 점프가 일어나야 하므로 JMP로 수정
004A567E JNZ 004A585F -> 점프가 일어나지 않아야 하므로 NOP으로 수정
위와 같이 패치를 하면 성공적으로 크랙을 할 수 있다.
3. Comment
Conditional jump만 패치하면 되는 간단한 문제였지만, 입력 값에 따라 에러 문구를 출력하기도 하고, 점프 여부가 달라지는 경우도 있어서 헷갈리는 문제였다. 또한 push + retn 조합은 JMP 명령어와 같다는 점을 배울 수 있었다.