Category : reverse engineering
Korea : HDD를 CD-Rom으로 인식시키기 위해서는 GetDriveTypeA의 리턴값이 무엇이 되어야 하는가 English : What value must GetDriveTypeA return in order to make the computer recognize the HDD as a CD-Rom |
Summary : GetDriveTypeA API
[+] Excute
바이너리를 실행하면 "Make me think your HD is a CD-Rom."이란 문구가 담긴 MessageBox가 나타난다.
MessageBox를 닫으면 Error라는 이름의 MessageBox가 다시 나타난다.
< Pic.1 >
< Pic.2 >
MessageBox의 내용들로 미루어보아 문제 바이너리에서 특정 Drive의 정보를 얻어오는데 , Drive의 정보를 CD-Rom으로 인식시켜야한다고 추측해볼 수 있다.
[+] Dynamic Analyse
Ollydbg를 이용해 동적으로 분석한다.
Ollydbg로 문제바이너리를 열어보면 바로 EP를 볼 수 있다.
00401000 >/$ 6A 00 PUSH 0 ; /Style = MB_OK|MB_APPLMODAL
00401002 |. 68 00204000 PUSH Reverse_.00402000 ; |Title = "abex' 1st crackme"
00401007 |. 68 12204000 PUSH Reverse_.00402012 ; |Text = "Make me think your HD is a CD-Rom."
0040100C |. 6A 00 PUSH 0 ; |hOwner = NULL
0040100E |. E8 4E000000 CALL <JMP.&USER32.MessageBoxA> ; \MessageBoxA
00401013 |. 68 94204000 PUSH Reverse_.00402094 ; /RootPathName = "c:\"
00401018 |. E8 38000000 CALL <JMP.&KERNEL32.GetDriveTypeA> ; \GetDriveTypeA 0040101D |. 46 INC ESI0040101E |. 48 DEC EAX 0040101F |. EB 00 JMP SHORT Reverse_.00401021 00401021 |> 46 INC ESI 00401022 |. 46 INC ESI 00401023 |. 48 DEC EAX 00401024 |. 3BC6 CMP EAX,ESI 00401026 |. 74 15 JE SHORT Reverse_.0040103D 00401028 |. 6A 00 PUSH 0 ; /Style = MB_OK|MB_APPLMODAL 0040102A |. 68 35204000 PUSH Reverse_.00402035 ; |Title = "Error" 0040102F |. 68 3B204000 PUSH Reverse_.0040203B ; |Text = "Nah... This is not a CD-ROM Drive!" 00401034 |. 6A 00 PUSH 0 ; |hOwner = NULL 00401036 |. E8 26000000 CALL <JMP.&USER32.MessageBoxA> ; \MessageBoxA 0040103B |. EB 13 JMP SHORT Reverse_.00401050 0040103D |> 6A 00 PUSH 0 ; |/Style = MB_OK|MB_APPLMODAL 0040103F |. 68 5E204000 PUSH Reverse_.0040205E ; ||Title = "YEAH!" 00401044 |. 68 64204000 PUSH Reverse_.00402064 ; ||Text = "Ok, I really think that your HD is a CD-ROM! :p" 00401049 |. 6A 00 PUSH 0 ; ||hOwner = NULL 0040104B |. E8 11000000 CALL <JMP.&USER32.MessageBoxA> ; |\MessageBoxA 00401050 \> E8 06000000 CALL <JMP.&KERNEL32.ExitProcess> ; \ExitProcess 00401055 $-FF25 50304000 JMP DWORD PTR DS:[<&KERNEL32.x>; kernel32.ExitProcess 00401061 $-FF25 5C304000 JMP DWORD PTR DS:[<&USER32.MessageBoxA>] ; USER32.MessageBoxA |
첫 번째 Challenge라 그런지 코드가 매우 간결하다.
문제바이너리는 "Make me think your HD is a CD-Rom."이란 문구를 Text 인자로 사용하여 MessageBoxA API함수를 호출한다.
00401000 >/$ 6A 00 PUSH 0 ; /Style = MB_OK|MB_APPLMODAL
00401002 |. 68 00204000 PUSH Reverse_.00402000 ; |Title = "abex' 1st crackme"
00401007 |. 68 12204000 PUSH Reverse_.00402012 ; |Text = "Make me think your HD is a CD-Rom."
0040100C |. 6A 00 PUSH 0 ; |hOwner = NULL
0040100E |. E8 4E000000 CALL <JMP.&USER32.MessageBoxA> ; \MessageBoxA |
MessageBox가 닫히면 "C:\"라는 문자열을 인자로 사용하여 GetDriveTypeA API함수를 호출한다.
GetDriveTypeA 함수는 인자로 Drive이름을 받아 해당 Drive의 Type를 돌려준다.
GetDriveTypeA 함수가 돌려주는 값은 아래표와 같다.
Return code/value | Description |
---|---|
|
The drive type cannot be determined. |
|
The root path is invalid; for example, there is no volume mounted at the specified path. |
|
The drive has removable media; for example, a floppy drive, thumb drive, or flash card reader. |
|
The drive has fixed media; for example, a hard drive or flash drive. |
|
The drive is a remote (network) drive. |
|
The drive is a CD-ROM drive. |
|
The drive is a RAM disk. |
분석을 이어서 진행해보면 , GetDriveTypeA함수 호출후에 아래의 루틴이 이어져있다.
0040101D |. 46 INC ESI 0040101E |. 48 DEC EAX 0040101F |. EB 00 JMP SHORT Reverse_.00401021 00401021 |> 46 INC ESI 00401022 |. 46 INC ESI 00401023 |. 48 DEC EAX 00401024 |. 3BC6 CMP EAX,ESI 00401026 |. 74 15 JE SHORT Reverse_.0040103D |
이 루틴은 ESI를 3을 증가시키고 , EAX는 2를 감소시켜 EAX와 ESI를 비교하여 두 값이 같다면 0x0040103D로 분기한다.
분기하지 않는다면 "Nah... This is not a CD-ROM Drive!"라는 문구를 가진 MessageBox가 나타난 후 종료되고 ,
분기에 성공했다면 0x0040103D에 있는 "Ok, I really think that your HD is a CD-Rom! :p"이란 문구를 가진 MessageBox가 나타나고 종료되는 루틴이 있다.
"Ok, I really think that your HD is a CD-Rom! :p" 문자열을 가진 MessageBox 나타나도록 해본다.
그러기위해선 GetDriveTypeA 함수 호출 직후의 ESI + 3 과 EAX - 2이 같아야하는데 , 호출 직후의 ESI 값은 0x00000000이고 EAX에는 GetDriveTypeA함수에서 돌려준 값이 담겨있다.
즉 , EAX - 2가 3이라면 분기하게된다. 따라서 EAX - 2 가 3이 되기위해선 EAX는 5여야한다.
GetDriveTypeA 함수는 위의 표에 나와있듯이 Drive의 Type가 CD-Rom 일때 5를 돌려준다.
이를 통해 위 루틴은 C:\ Drive가 CD-Rom인지를 검사하는 루틴임을 알 수 있다.
그러므로 GetDriveTypeA 함수 호출직후에 EAX를 5로 변경해준다면 분기할 수 있다.
< Pic.3 GetDriveTypeA 호출직후 EAX를 5로 변경>
함수호출 직후 EAX를 5로 조작해주고 진행하면 아래와 같은 화면을 볼 수 있다.
답 : 5