베이직 1번 문제는 하드디스크를 시디롬 드라이브로 인식시키기 위한GetDriveTypeA함수의 리턴값을 알아내는 것입니다.
우선 사이트에 주어진 다운로드 파일을 다운로드 한 후 파일을 그냥 열어보면,
"내가 너의 하드디스크를 시디롬 드라이브로 생각하게 만들어" 라는 문구가
뜨고 확인을 누르면,
"아,, 이건 시디롬 드라이브가 아니야!" 라는 문구가 뜹니다.
여기서 확인을 누르면 그대로 종료됩니다.
이 실행 결과를 통해 우리는 실행파일이 첫 번째 창에서 두 번째 창으로 넘어갈 때 무언가를 검사하고 그 값에 따라 두 번째 창이 달라진다는 것을 알 수 있습니다.
그럼 이제 OllyDbg로 파일을 열어봅시다.
OllyDbg를 킨 후 [F3]를 누르면
이렇게 파일을 선택하여 불러올 수 있습니다.
짠
혹시나 올리디버거를 안쓰는 분들을 위해 설명을 드리자면,
1_주소 영역
2_OP코드 영역
3_디스어셈블리 영역
4_레지스터 영역
5_설명 영역
6_메모리 덤프 영역
7_스택 영역
입니다.
코드를 대충 보니
MessageBoxA 는 메세지를 띄우는 함수인 것 같고
GetDriveTypeA 함수의 리턴값부터 알아야할 것 같네요.
그러므로,
요로콤 GetDriveTypeA 함수에 BP(BreakPoint)를 걸어줍시다.
그 후 실행시키면
EAX레지스터의 값이 3으로 변해있습니다.
EAX레지스터는 함수의 리턴값을 반환해주므로 GetDriveTypeA의 리턴값은 3임을 알 수있습니다.
계속 한줄한줄 실행해봅시다.
ESI 의 값은 세 번 올리고
EAX 의 값은 두 번 내리네요.
그 후 EAX와 ESI의 값을 비교한 뒤 비교한 결과가 같으면 JE명령어를 통해
이 부분으로 오고 비교한 결과가 다르면
이 부분으로 오게 됩니다.
그런데 위에서
ESI 의 값은 세 번 올려 3이 되었고
EAX의 값은 두 번 내려 1이 되었으므로 둘을 비교하면 당연히 0이 반환되어 (CMP명령어는 비교하였을 때 거짓일경우, 0을 반환)실패 메세지를 띄우는 함수로 들어가게됩니다.
그러므로 성공 메세지를 띄우기 위해선 4 가지 방법이 있습니다.
1. GetDriveTypeA 함수의 CD-ROM 드라이브 리턴값을 알아온다.
2. ESI(EAX)의 값을 EAX(ESI)의 값과 같게 바꿔준다.
3. JE명령어를 JMP명령어로 바꿔준다.
4. CMP 명령을 바꾼다.
일단 코드엔진의 문제는 GetDriveTypeA함수의 리턴값을 알아오는 것이므로 방법1로 풀자면,
EAX = 1
ESI = 3
=>EAX의 값이 2 더 증가해야 함 =>GetDriveTypeA함수의 리턴 값이 3+2였어야 함
따라서 GetDriveTypeA함수의 CD-ROM드라이브의 리턴값은 3+2임을 알 수 있습니다.
코드엔진 문제의 답을 알았으니 남은 방법으로 풀어볼까요?
방법 2 : CMP명령어가 실행되기 바로 전, 모든 연산이 끝난지점에서 ESI 의 값을 EAX의 값으로 수정해주면 됩니다.(또는 EAX 의 값을 ESI의 값으로 수정)
방법 3 : JE명령어를 JMP명령어로 바꾼 후 실행하면 됩니다.
(추가로
이 부분에서 뒤쪽의 주소를
이곳으로 바꾸어도 됩니다.)
방법 4 : CMP 명령어는 두 레지스터를 비교해주는 것이므로
CMP EAX,ESI 를 CMP EAX,EAX 또는 CMP ESI,ESI 로 바꾸면 됩니다.
-----------------------------------------------
사실
https://docs.microsoft.com/ko-kr/windows/desktop/api/fileapi/nf-fileapi-getdrivetypea 에서 GetDriveTypeA함수의 CD-ROM 드라이브의 리턴 값만 알아오면 되는 문제지만 그래도 손수 푸니 재밌네요.
'Security > CodeEngn' 카테고리의 다른 글
CodeEngn_Basic_06 (0) | 2018.08.12 |
---|---|
CodeEngn_Basic_05 (0) | 2018.08.09 |
CodeEngn_Basic_04 (0) | 2018.08.07 |
CodeEngn_Basic_03 (0) | 2018.08.04 |
CodeEngn_Basic_02 (0) | 2018.08.03 |