코드엔진(codeengn) basic 1 문제풀이

문제풀이/Codeengn 2018.07.17 댓글 Plorence

문제 보기

코드엔진 챌린지 : basic 01 문제

GetdriveTypeA함수는 WIN API이기때문에 MSDN(클릭시 GetDriveTypeA 함수 문서로 이동합니다.)를 참고하면 됩니다.

Download버튼으로 파일을 다운로드 한후 DIE(Detect It Easy)를 실행시켜 PE를 스캔한후 Exe32인지 Exe64인지 확인합니다. 이것을 확인하는 이유는 x86dbg로 실행 시켜야 할것인지 x64dbg로 실행할건지 결정됩니다.

PE스캔 결과 이미지

델파이로 제작이 되었고,Exe32입니다. 그래서 디버거는 x86dbg실행시켜야 합니다.

프로그램 엔트리포인트에 도달 이미지

파일 -> 열기(F3)을 눌러 리버싱할 파일을 선택한후에 실행(F9)하여 엔트리포인트(EntryPoint)까지 도달합니다.

아무것도 안한상태에서 실행만 계속하면 아래와 같은 메시지 박스가 뜹니다.

에러 메시지박스 이미지

다시시작(S)를 하고 다시 엔트리포인트까지 진입을 해줍니다. 그리고 1줄씩 분석을 해봅시다.

처음 메시지박스를 출력하는 부분 이미지

처음에 Text는 "Make me think your HD is a CD-Rom.",Caption명은 "abex' 1st creakme"와 그외 인자들을 전달해주고 WIN APIMessageBoxA를 호출하게 됩니다.

메시지박스 출력 이미지

push reverse_lo1.40294 부분은 함수호출을 위해 인자를 전달해준거고 (인자는 C:\\) 그다음 GetDriveTypeA라는 WIN API 함수가 호출됩니다. 이 함수의 리턴값 eax 레지스터에 저장됩니다.

GetDriveTypeA함수의 반환값 확인 이미지

WINAPI GetDriveTypeA함수를 호출한 다음구분BreakPoint를 걸고 실행을 해보면 EAX 레지스터GetDriveTypeA의 반환값이 들어있다는걸 알 수 있습니다.

GetDriveTypeA함수 호출후의 다음 구문 이미지

ESI레지스터의 현재 값 이미지

INC esi는 피연산자에 1을 더합니다. 이 구문이 실행되고 나서 피연산자는  esi가 되고 1을 증가시키면 00401001이 됩니다.

inc esi의 구문실행 후 다음 구문 이미지

Dec라는 옵코드는 Inc와 반대로 피연산자에서 1을 뺍니다. 위에서 eax의 값이 3인걸 확인했으니 이 구문이 실행되면 eax의 값은 2가 됩니다.

dec eax의 구문실행 후 다음 구문 이미지

jmp피연산자 위치로 이동됩니다. reverse_l01.401021의 위치는 다음구문인 inc esi입니다.

그다음 inc esi에서는 위에서도 봤듯이,00401001에서 1을 더해준값인 00401002 가됩니다. 마지막 구문은 똑같으므로 esi의 값은 00401003이 됩니다.

ESI 레지스터의 현재 값 이미지

inc esi의 구문실행 후 다음 구문 이미지

먼저 dec eax 구문실행을 통해 eax레지스터의 값이 1이 됩니다.

그다음 cmp이라는 옵코드(Opcode)는 두 개의 피연산자의 값같으면 아래의 구문,je을 통해 reverse_l01.40103D로 이동합니다.

cmp,eax,esi구문의 결과값이 참일때 실행되는 구문 이미지

제일 처음 push 0의 부분이 reverse_l01.40103D입니다.

이동하게 되면 성공했다 내용을 담고있는 WINAPI MessageBox함수가 호출됩니다.

cmp eax,esi의 구문이 참이 아닐때 이미지

참이 아니라면 이동하지 않고 바로 다음구문을 실행합니다.

그래서 결국에는 실패했다는 내용을 담고있는 WINAPI MessageBox를 호출합니다.

실패시 이동하는 위치(빨간 화살표 참고) 이미지

실패시 WINAPI MessageBox함수호출하고 나서 reverse_l01.401050으로 이동합니다.

reverse_l10.401050WINAPI ExitProcess함수를 호출하는 구문입니다. 그리고 나서 프로그램이 종료됩니다.

결국엔 어떻게 하는가?

아까 cmp eax,esi구문에서 거짓이 아닌 참이되게 만들어주면 됩니다.

다음구문인 je의 옵코드는 참이어야 이동하게 됩니다.

  다시실행(S)을 해준후 아까처럼 엔트리포인트까지 도달합니다.

그리고 두 개의 피연산자를 비교하는 구문에 BreakPoint를 걸어줍시다.

두 개의 피연산자 비교 구문 이미지

BreakPoint를 걸어주고 실행을 했다면 BreakPoint한곳에 도달하게 됩니다.

그러면 레지스터창에서 ESI을 더블클릭하여 EAX와 값이 동일하게 바꿉니다.

ESI 값 수정 이미지

값을 EAX와 동일하게 1로 수정했으면 확인 버튼 이후 실행(S)하면됩니다.

성공 했다는 결과 이미지

그러면 "OK I really think that your HD is a CD-ROM! :p"라는 문구가 포함된 MessageBox함수호출됩니다.

성공했다는 의미입니다.

성공했다는 MessageBox함수 호출 이후 구문 이미지

순서대로 함수 호출이후에 프로세스를 종료하는 ExitProcess함수호출됩니다. 그리고 프로그램이 종료됩니다.

혹시 성공했다는 메시지박스를 출력하기 위한 다른방법은 없나?

inc esi 구문 실행 전 이미지

inc esi라는 구문 실행전에 구문을 성공했다는 의미의 메시지박스를 출력하는 위치를 이동하게끔 하면됩니다.

inc esi구문을 더블클릭해 위와 같이 jmp 이동할위치를 써주고 확인을 누르고 실행(S)를 눌러주면 성공의 의미의 메시지박스가 뜨게됩니다.

성공했다는 결과 이미지

이걸로 문제 풀이는 끝났습니다.

감사합니다.

댓글