leejhstory

리버싱 입문 6장(지뢰찾기 게임 해킹) 본문

디지털 포렌식 & 리버싱/리버싱

리버싱 입문 6장(지뢰찾기 게임 해킹)

LeeJHstory 2021. 12. 16. 14:32

지뢰 찾기 게임 해킹

  • ALSR(Address Space Layout Randomization)

: PE 파일을 메모리에 로딩할 때 Image Base를 랜덤하게 설정하는 기술. 다시 말해 디버거로 다시 시작할 때마다 코드 주소가 계속 바뀐다. Image Base에 RVA가 더해져서 VA가 생성되는데, ASLR을 통해 Image Base는 변경되지만 RVA는 변경되지 않기 때문에 뒤의 4자리는 그대로 있음.

 

  1. 시간 설정 변경

1.1 디버깅 시작하기

: 지뢰찾기는 게임을 수행한 시간이 화면에 표시된다. 지뢰찾기 프로그램을 리버싱하여 시간을 임의대로 변경해 본다. 모든 동작을 알아내기엔 시간이 많이 필요하므로 SetTimer() 함수를 사용한다는 가정으로 부터 출발해본다.

실행버튼(F9)을 눌러 프로그램이 사용자의 입력을 기다리는 상태까지(Running) 실행되도록 한다. 실행파일을 디버깅 하는 또 다른 방법으로는 지뢰찾기를 먼저 실행하고 나서 실행중인 프로세를 디버거에 붙이는(Attach) 기능을 사용하여 Running 상태인 프로그램을 디버깅할 수도 있다. 

 

1.2 SetTimer() 함수 호출 영역에 브레이크포인트 설정

  1. 실행중인 프로세스를 붙이면 엔트리 포인트에서 프로그램이 멈추는 것이아니라 현재 실행중인 모듈에서 프로그램이 멈춘다. 
  2. 디버거 상단에서 ntdll에서 프로그램이 멈춘것을 확인가능하다. 지금은 minesweeper 모듈을 분석해야 하므로 코드영역에서 우클릭 하여 [View] ->  [minesweeper] 모듈을 선택한다.
  3. 화면 상단에 minesweeper 모듈이 선택된 것을 확인할 수 있다.

  1. SetTimer() 함수의 호출 위치를 찾기 위해 [Search for] -> [All intermodular calls] 메뉴를 클릭.
  2. USER32.SetTimer() 함수를 찾아 브레이크포인트(F2)를 설정.

  1. 실행중인 프로세스를 Attach 하여 디버거 상태가 Pause이므로 F9를 눌러 Running로 상태를 변경하여 브레이크 포인트를 설정한 곳에 멈추는 것을 확인.

 

1.3 SetTimer() 호출 부분 코드 분석

: SetTimer() 함수는 4개의 인자를 입력으로 받아들임.

  • uElapse : 타임아웃 시간 간격을 결정. milliseconds 단위, 1000이 들어가면 1초에 한번씩 타이머가 동작함

 

  • 디버거에서 BP가 걸린 SetTimer() 호출 부분을 살펴보면, 4번의 push로 인자를 넘겨주고 그 중에 push 3e8명령어를 발견할 수 있음
  • hex code 3e8은 1000을 의미. Assemble메뉴를 선택하여 주소에 있는 숫자를 5000을 의미하는 1388로 바꾸면 타이머 동작 시간을 5배로 늘릴 수 있다.(push 3e8 -> push 1388)

 

1.4 타이머 조작

  • 마우스 우클릭 -> [edit] -> [Copy all modifications to executable] 메뉴 선택 -> 마우스 우클릭 -> [Save file…] 클릭하여 파일형식을 ‘Executable file or DLL’로 지정.
  • MineSweeper2로 저장후 실행하면 화면의 시간이 5초에 하나씩 증가하는 것을 확인할 수 있다.

 

  1. 지뢰 찾기 맵핵 만들기

2.1 지뢰찾기 함수 및 기능 찾기

  • GetKeyState : 타일을 눌렀을 때 호출 되는 함수. 
  • ShowBombs() : 폭탄을 보여주는 함수

2.2 ShowBombs() 함수 분석

  • ShowBombs 함수의 인자값을 참고하면 GameOver라는 함수에서 호출 되었음을 알 수 있다.
  • GameOver() 함수의 주소(0x100347C)를 확인한 후 아래 CALL(0x1002F80)되는 곳 위에 인자인 PUSH 값을 확인보니 0A가 들어가는 것을 볼 수 있다.

  • ShowBombs 함수의 인자가 0A인것을 확인

  • [Help]-[Content] 버튼을 누르면 도우말 창이 뜨는 대신 지뢰가 보이도록 한다.

  • Strings검색으로 NTHelp.chm 문자열이 있는 곳으로 이동

 

  • 도움 창을 띄우는 함수의 시작 주소는 0x1003D76 이고 합수의 시작을 도움 창이 뜨는 것이 아니라 폭탄을 보여주는 함수를 호출해본다.

  • 인자인 0A를 넣어주고 함수를 CALL 한 다음 함수를 수행하지 않도록 하기 위해 함수의 끝으로 JMP 한다.
  • ruturn 8은 함수호출규약 중 _stdcall으로 8(인자 2개) 만큼 함수 안에서 스택을 처리한다는 뜻.
  • 도움말 함수를 수행하지 않아 스택을 사용하지 않았으므로 정리하지 않도록 8을 지운다.

  • 변경한 어셈블리어를 저장하기 위해 [Copy to executable]-[All Modifications]를 눌러 Copy all을 클릭한다.

  • 위와 같은 창이 뜨면 마우스 우클릭하여 [Save file]를 클릭
  • [F1] 또는 [Help]-[Contents]를 클릭하면 지뢰가 표시된다.

1~4장 정리한것 위치

https://docs.google.com/document/d/1yi7nHeffi6v_ojxFjysOb1OAIsz6bfPu8NwbtQ8kU0o/edit?usp=sharing

Comments