지뢰찾기를 자동으로 풀어버리는 프로그램을 만든다.
을 먼저 읽어보면 도움이 될듯.
핵심원리
1. 지뢰찾기의 지뢰 정보를 가지고 있는 메모리 덤프를 찾음.
2. 지뢰정보를 받아옴.
3. 지뢰찾기 프로그램에 지뢰가 아닌 부분을 모두다 마우스 클릭하는 입력을함.
프로그램 폼
메모리 덤프를 읽어오는 부분 최대크기의 지뢰판을 형성하면 최대 864의 크기만큼 담기므로 864로 하였다.
while(true) { //행 populate if (buffer[x + y * 32] + buffer[x + 1 + y * 32] != 0x20)//의미있는 열임. { while (true) { //열 populate //buffer[x + y * 32] 주소임 if (buffer[x + y * 32] != 0x10) { if (buffer[x + y * 32] != 0x8F) click(x, y); x++; } else { y++; x = 1; break; } } } else break; }
지뢰정보를 어떻게 읽어올지 고민을 해봤는데
1,1에서 x좌표를 계속 증가시키다가 0x10(지뢰아님) 0x8F(지뢰) 둘다 아닌경우 다음 행으로 넘어감.
지뢰찾기에 마우스 이벤트를 보내는 부분.
지뢰한블록당 32px이므로 칸단 16px씩 이동하면 된다.(단위가 px인지는 모르겠지만 하여튼 들어맞음)
또한 시작지점은 18,60정도로하면 1,1의 지뢰부분이다.
그리고 가장중요한건데 메시지를 보낼때 이동할 좌표값을 넣는건데 쉬프트 연산자가 필요하다
x와 y로 이루어진 값들을 하나의 값으로 표현한뒤에 그것을 보내줘서 인식시키는데
int value = (y_start + (y-1)*16 << 16) + x_start + (x-1)*16;
SendMessage(process.MainWindowHandle, 0x20, (uint)value, 0x000000001);
SendMessage(process.MainWindowHandle, 0x20, (uint)value, 0x020100001);
PostMessage(process.MainWindowHandle, 0x201, 0x000000001, (uint)value);
PostMessage(process.MainWindowHandle, 0x202, 0x000000000, (uint)value);
보면 value가 x와 y로 이루어진 값이다.
직접 microsoft spy++을 봐보면 좌표부분의 데이터를 전송할때 0x???????? 이런식으로 보낸다.
그중에 앞의 4개의 ????가 y좌표를 나타내고 뒤의 ????가 x좌표를 나타낸다. 물론 16진수로 나타내어져있다.
따라서 x와 y의 값으로 나타내기위해서는 먼저 y좌표에 2^16을 곱하여 왼쪽으로 4칸이동시키고 x좌표값은 그냥 더해주면된다. 16진수로 바꿔줘야하고
그렇게 보내면 프로그램이 원하는 좌표로 이동하여 보내진다.
해당 프로젝트 파일
'보안 > 리버싱' 카테고리의 다른 글
reversing - minesweeper (0) | 2017.01.25 |
---|