윈xp용 지뢰찾기를 리버싱 하여 맵핵을 만들어 보자!
이번 문서에서는 약간 편법을 사용하여 폭탄이 생성된 곳을 확인하고 맵핵을 제작할 것이다.
먼저 지뢰찾기 게임을 ida에 넣고 분석해 보았다.
함수명을 bomb로 검색해 보자.
폭탄을 그리기도 하고, 수를 세기도 하고 폭탄을 보여주기도 하는 여러가지 함수들을 볼 수 있다.
이중 ShowBombs함수를 들어가 보자.
이 함수를 유심히 살펴보면 선언되지 않은 xBoxMac, YBoxMac 변수가 있다.
전역변수에 저장되어 있는 폭탄의 위치가 이곳에 저장되어 있다고 유추할 수 있다.
이 부분을 ollydbg를 통해 확인해 보자.
다음과 같이 지뢰찾기 게임의 맵으로 생각되는 부분이 배열로 저장되어 있다.
드물게 등장하는 8F를 지뢰로 생각하고 대조해 보면 위치가 일치한다.
분석해 보면, 10은 개행, 8F는 폭탄, 0F는 아직 누르지 않은 블록이라는 것을 알 수 있다.
이부분을 불러와 맵핵을 만드는 코드를 짜 보았다.
from ctypes import *
from ctypes.wintypes import *
import struct
def getpid(process_name):
import os
return [item.split()[1] for item in os.popen('tasklist').read().splitlines()[4:] if process_name in item.split()]
OpenProcess = windll.kernel32.OpenProcess
ReadProcessMemory = windll.kernel32.ReadProcessMemory
CloseHandle = windll.kernel32.CloseHandle
lenth=1200
PROCESS_ALL_ACCESS = 0x1F0FFF
pid = int(getpid("winmine.exe")[0])
address = 0x1005360
buffer = c_char_p(b" "*lenth)
val = c_int()
bufferSize = len(buffer.value)
bytesRead = c_ulong(0)
processHandle = OpenProcess(PROCESS_ALL_ACCESS, False, pid)
if ReadProcessMemory(processHandle, address, buffer, bufferSize, byref(bytesRead)):
print("Success:" + str(val.value))
else:
print("Failed.")
CloseHandle(processHandle)
buffer = str(buffer).split('\'')[1]
flag=0
for i in range(0,lenth*4):
if i%4==2:
if buffer[i] == '1':
if flag%2==1:
print "\n",
flag+=1
if buffer[i] == '0' and flag%2==1:
print "O",
if buffer[i] == '8':
print "*",
다음과 같이 코드를 완성하여 맵핵을 제작하였다.
완성!