CodeEngn Reversing Basic_Level01

실행해보면 다음과 같은 창이 뜬다. HD를 인식하는 부분을 찾아야 할 것 같다.

올리디버거에 올려 차근차근 실행해본다. 어느 코드에서 왜 창이 뜨는 지를 찾아보자.

이 라인을 실행하니 원하지 않는 창이 뜬다. 이 명령어는 어느 경로를 통해 실행하게 되는가?

위에서 점프를 하지 않으면 실패 메시지를 Push하고 메시지 박스를 띄운다. 즉, 위에서 점프를 한다면 실패 메시지를 띄우지 않겠다.

JE일 때 점프를 하지 않았으니, JNE로 바꿔보았다. (JNE로 바꾸니 JNZ로 바뀌었다. 이 둘은 같은 기계어이므로 동일한 의미이다.)

이렇게 하면 성공 메시지를 띄울 수 있다. 하지만 단순히 점프문을 변경하는 것보다 좀 더 근본적으로 문제를 풀어볼 필요가 있다.

원본 코드의 JE에서 점프하지 않았기 때문에 에러 메시지를 뜨운 것이었다. 그렇다면 무엇을 비교했던 걸까? 그 값은 어디서 나온 것일까?

JE 위에 CMP가 있다. 점프를 할 지 안 할 지 결정하는 레지스터가 EAX와 ESI라는 것을 알 수 있다. 그렇다면 EAX와 ESI에 저장된 값의 근원을 찾아보자.

CMP를 실행하기 전 GetDriveTypeA 함수를 실행하여 EAX가 3으로 설정된다. ESI는 처음부터 0이였다.

GetDriveTypeA 함수와 CMP코드 사이의 코드이다. ESI를 총 3만큼 더하고, EAX를 총 2만큼 뺀다. 중간의 점프는 바로 아래 있는 코드로 점프한다. (리버서를 헷갈리게 만드는 더미 코드로 보인다)
그러면 EAX값을 설정해주는 GetDriveTypeA 함수를 살펴보자. 올리디버거에 잡힌 심볼을 보니 GetDriveTypeA함수는 Kernel(OS)과 관련이 있어 보인다.

GetDriveTypeA함수가 Kernel(OS)과 관련이 있어 보여 인터넷 검색을 했다. 그러자 리턴값에 대한 정보를 찾을 수 있었다.


쿼리한 문자열 경로의 드라이브 유형이 CDROM이면 return값은 5가 되어야 한다.
GetDriveTypeA 함수를 호출하기 전에 인자로 “C:“라는 문자열을 넣어주고 있다. 내 C드라이브는 하드이기에 함수 리턴값으로 3을 반환한다. 그래서 EAX가 3으로 설정되었다.
이를 해결하여 성공 메시지를 띄우기 위해서 여러가지 방법이 가능하겠다.
- 점프문 수정/삽입
- 함수 인자를 CDROM의 경로로 수정
- 함수를 나온 뒤 eax가 5로 설정되도록 수정
- 값에 상관 없이 ESI == EAX가 되도록 수정
- … 무엇이든 마음대로

Cmp하기 전에 ESI에 EAX의 값을 넣도록 코드를 수정했다. 코드를 수정할 때에는 파일 크기가 정해져 있다는 점에 주의해야 한다.
코드의 크기가 수정하는 원본 코드보다 크면 다음 코드를 침범하게 된다. 다음 코드를 침범하면 코드가 깨지게 되어 원치 않는 행동을 할 수 있다.
수정한 EXE를 저장해 새로운 EXE 파일을 만드려면 다음과 같이 하면 된다.
