http://codeengn.com/challenges/
위 링크(코드엔진) 사이트에서 제공하는 abex문제를 풀어보겠습니다.
<▲ 사진 01>
분석.
Level 01에 파일은 다운로드 하여 실행시켜보면 아래와 같은 알림창이 뜹니다.
<▲ 사진 02>
"Make me think your HD is a CD-Rom."이라는 문구가 출력되는데. 처음에는 무슨 뜻인지 몰랐으나,
뒤에 CD-Rom을 보고나서 HD가 HDD(Hard Disk)를 말하는 건가? 라는 생각을 했습니다.
"확인"버튼을 클릭하면 아래와 같은 알림창이 뜹니다.
<▲ 사진 03>
"Nah... This is not a CD-ROM Drive!" 라고 뜨면서 Error창이 뜹니다.
<▲ 사진 04>
(VC++, VC, Delphi 등의 개발툴을 사용하면 자신이 작성한 소스코드 외에 컴파일러가 Stub Code를 추가시킴)
어셈블리 코드를 보면 MessageBoxA함수가 가장먼저 호출되고, 메시지박스의 내용은 앞서 봤던 <사진 02>의 내용입니다. 그리고나서 GetDriveTypeA함수가 호출됩니다. 함수이름만으로 드라이브의 타입을 구해오는 함수일것 같다는 생각이 듭니다. GetDriveTypeA함수에 대해 검색해 보았습니다.
<▲ 사진 05>
디스크 드라이브가 이동식인지, 고정인지, CD-ROM, RAM 또는 네트워크 드라이브인지 확인하는 함수라고 되어있습니다.
<▲ 사진 06>
리턴 값으로는 여러가지가 있는데 눈에 띄는 부분이 DRIVE_FIXED(3)과 DRIVE_CDROM(5)부분입니다. 하드디스크나 플래시드라이브 같은경우는 GetDriveType함수의 리턴값이 3이 리턴되고, CD-ROM일 경우는 5가 리턴됩니다.
우리는 하드디스크를 CD-ROM으로 둔갑(?)시키면 되므로, 리턴값이 5가 나오게 변경하면 될것 같습니다.
GetDriveTypeA함수까지 실행하고 나서 어떤 리턴값이 출력되는지 살펴보겠습니다.
<▲ 사진 07>
GetDriveTypeA 함수가 실행되고 난 리턴값이 3으로 셋팅 되는것을 확인 할 수 있습니다.
<▲ 사진 08>
그리고나서, ESI와 EAX를 증가, 감소하다가 CMP EAX, ESI로 비교합니다.
CMP EAX, ESI 부분까지 디버깅해보니, EAX는 1값이 저장되어 있고, ESI는 3값이 저장되어 있습니다.
서로 값이 다르기 때문에 바로 아래명령어 JE SHORT Reverse_.0040103D 명령어를 실행시키지 않고,
바로 아래의 MessageBoxA함수를 실행시킵니다.
(EAX와 ESI의 값이 같다면, JE 명령어를 통해 40103D 주소로 점프를 하게되고, 해당 주소에는 "Ok, I really thick that your HD is a CD-ROM! :p"를 출력하는 메시지박스를 띄우며 크랙이 완성된다.)
다시 디버깅을 시작하여 40101D주소 부분(GetDriveTypeA함수를 시작한 직후)에서 EAX값을 5로 셋팅해보자.
<▲ 사진 09>
<▲ 사진 10>
성공적으로 메시지 박스를 출력하는 것을 볼 수 있다.
크랙 첫번째.
<▲ 사진 11>
크랙하는 방법은 여러가지가 있습니다. 제가 생각한 첫번째 방법으로 EAX값을 5로 바꾸는 것이 아닌, 아랫부분에 EAX와 ESI의 값을 증감하는 과정을 수정하여 비교부분에서 서로 값이 같도록 변경하였습니다. (원본 어셈블리코드 사진 04와 비교해 보시기 바랍니다.)
크랙 두번째.
<▲ 사진 12>
두번째 방법은 묻지도 따지지도 않고 바로 점프 시켜버리는 방법입니다.
CMP명령어로 EAX와 ESI를 비교하던 말던 바로 40103D주소(성공 메시지 출력 부분)로 점프시켜 버리는 방법입니다.
이렇게 크랙하는 방법은 여러가지 방법이 존재합니다. 무조건 다른사람의 방법을 따라하지 말고, 자신이 생각해보고 생각대로 해보고 시행착오를 많이 경험하다보면 실력이 향상 되겠죠?