베지밀

[리버싱] 지뢰찾기 무적판 Ollydbg로 패치하기 본문

개인 공부/리버싱

[리버싱] 지뢰찾기 무적판 Ollydbg로 패치하기

vegimil 2023. 10. 31. 03:33

winmine.zip
0.08MB

혼자 공부하는 글이라 설명이 불친절 할 수 있음. 인터넷 검색을 통해 해결했다

Ollydbg로 분석해보자 (추후 x32dbg로 분석해볼 예정)

 

32비트 파일이다.

 

지뢰찾기 바이너리에서 이용될 함수 추론해보기

- 지뢰 무작위 배치하는 함수 (srand로 구현)

- 지뢰를 클릭했을 때 보여주는 함수

- 사용자 입력, 즉 클릭할 때 실행되는 함수

 

 

srand부분에 bp를 걸었다.

srand부분에서 쭉 돌다보니 0x10036C7부터 0x1003703 부분을 반복한다.

1005334의 값은 9이다.

1005330의 값이 9부터 줄어들다가 1이 지나면 탈출한다. 1005334의 값(9)부터 0까지 하나씩 줄어드는 것 같다.

지뢰찾기 초급 게임의 지뢰 수는 10개이므로 다음과 같은 사실을 알 수 있다.

1005334 -> 지뢰의 갯수

1005330 -> 지뢰를 하나씩 배치할 때마다 count

덤프창에서 메모리주소 1005330의 값을 확인해보면 1005334에는 9, 1005330에는 0이 들어있다. (0~9까지 총 10개)

이후에는 0F와 8F가 난무하는 메모리 코드를 볼 수 있다. 반복문 돌 때 해당 값의 변화를 보기 위해 재실행했다.

덤프창을 1005330으로 띄워놓고 f8 노가다로 확인해보면 메모리에 ? 값이 하나씩 생기는 걸 볼 수 있다. 아마 저 0x8F가 지뢰를 표시하는 곳인 것 같다.

저 부분에 하드웨어 브레이크 포인트를 걸어보자.

우클릭>Breakpoint>Hardware on execution로 bp를 걸 수 있고, Debug > Hardware Break Points로 확인 가능하다.

f8 노가다로 bp를 걸어본 결과

1002F80 위치에 bp를 걸면 지뢰를 밟았을 때 bp에 걸린다.

ctrl+f9로 리턴값까지 오면 비로소 지뢰가 다 표시된다.

1002379~10023AF의 반복문은 사용자의 입력값(=클릭)을 받는데, 이 부분에다가 1002F80으로 JMP 하도록 패치해보자.

 

1002379~ 이후의 적절한 위치에서 CALL을 통해 1002F80함수를 실행시켜서 지뢰판을 보이게 한 후, NOP 명령으로 종료되게 하기 위해 메모리의 빈 공간을 활용해보자.

사용자 입력 칸->JMP로 빈공간 이동->CALL로 지뢰 표시하는 함수 실행 후 NOP 명령으로 종료

 

메모리의 빈 공간 이용

빈 공간에 1002380위치에 있던 명령어를 그대로 입력하고 지뢰 표시 함수를 CALL한다. 이후 NOP 명령어로 가기 위해 1002385로 JMP한다.

(push 0a 안했다가 프로그램 실행하자마자 종료됨)

사용자 입력받는 부분에 빈공간으로 JMP하도록 수정하고, Copy to executable>All modification으로 패치 파일을 저장한다.

이렇게 실행하자마자 모든 지뢰가 보이는 지뢰찾기 패치가 끝났다.