Windows 게임 지뢰 찾기를 탐색하는 보안 테스트

저자:  Jingdong Industry 의 Wan Yuxin

어릴 때부터 지뢰 찾기 게임을 해본 사람이 많다고 생각하는데, 컴퓨터 게임이 많지 않던 그 시절에 지뢰 찾기는 가장 인기 있는 게임 중 하나가 되었고, 나중에 나도 한 번 해보고 싶은 충동이 생겼다. 동적 디버깅, 리버스 엔지니어링 및 C를 통해 지뢰 찾기 보조 도구를 작성하여 리버스 엔지니어링 및 코딩 기술을 향상시킵니다.

동적 디버깅(분석)

먼저 지뢰 찾기 프로그램의 동적 디버깅(분석)을 수행합니다.

OD ( ollydebug 도구 )를 열고 지뢰 찾기를 OD로 드래그 드롭 하고 F9 실행 하여 실행 합니다 . 두 번째는 API rand 함수를 통해 돌파구를 찾는 것입니다 . 지뢰 찾기 창의 지뢰밭에서 임의의 위치( 그림에 2가 나타남 )를 클릭한 다음 아래 그림과 같이 복원([웃는 얼굴] 버튼 - )을 클릭합니다.



이때 OD는 아래 그림과 같이 방금 설정한 rand 의 중단점에서 중단됩니다.



 

랜덤함수 rand 를 찾아 다음 스택은 역추적하여 푸시 (push into the stack)의 매개변수 를 찾기 위해 상위 레벨 함수 , 즉 랜덤 생성 함수( rand )는 임의로 생성된 높이, 폭, 천둥. K (콜 스택)을 클릭하여 K 콜 스택 창을 띄우고 , 스택 창 정보를 보고, 리턴 주소를 찾고, K 콜 스택 창 에서 리턴 주소를 더블 클릭하여 이전 레이어로 돌아가는 과정을 호출한다. 스택 역추적. 아래 그림에서 스택 정보 010036D2 (리턴 주소)를 주의 깊게 관찰하십시오 .







단일 단계 F8 , 아래와 같이 레지스터, 데이터 창 및 스택 창 변경 사항, dword ptr ss:[esp+0x4] 또는 dword ptr ds:[XXX] 데이터 창 추적 값( 000DFC44 값은 09 )을 관찰합니다.

상위 수준 함수로 돌아온 후 내부 명령을 분석하고 아래 그림과 같이 임의의 rand 에 의해 생성된 너비( 09 )를 알 수 있습니다 . 주소 010036C7 에 주목하십시오 .

먼저 이 함수에 의해 반환된 결과에서 eax를 분석합니다 .한 단계 후에 아래 그림과 같이 숫자 09 가 스택(주소 010036D2 ) 에 푸시되는 것을 확인할 수 있습니다.



위의 분석을 통해 기본적으로 주변 랜덤함수 rand 발생률이 높고, 천둥번개임을 짐작할 수 있다. 아래 그림과 같이 지뢰찾기 설정(커스텀 지뢰밭)을 변경하여 rand 함수를 정확하게 찾아 매개변수를 전달하고 [확인]을 클릭한 후 [복원(웃는 얼굴 - )] 버튼을 클릭할 수 있습니다.



 

아래 그림과 같이 OD를 관찰하십시오 .



 

푸시 0C ( 000DFC84 의 값은 0C ) 임을 알 수 있으며 , 이 rand 함수 의 푸시 0C가 지뢰밭의 높이라고 판단할 수 있습니다 . 동시에 메모리 영역에 대략적인 지뢰밭 그래픽을 선명하게 볼 수 있는데, 위의 방법을 통해 0x80이 지뢰밭임을 대략적으로 짐작할 수 있습니다. 또는 IDA 와 함께 분석하거나 정적 분석을 통해 프로그램 로직을 보다 직관적으로 볼 수 있습니다. 아래 그림과 같이 기본 주소, 광산 번호 및 기타 정보와 같은 데이터를 가져옵니다.







 

위의 코드는 아마도 전역 폭 0x09 , 높이 0x0C , 천둥수 0x0A 의 변수를 먼저 설정 하고 두 층의 루프를 판단하여 폭과 높이를 임의로 생성한다는 의미일 것입니다. 지도 기본 주소 가져오기: 0x01005340 . 아래 그림을 분석하면 광산이 0x0F , 광산이 0x8F , 벽이 0x10 이라는 것을 알 수 있습니다 .







 

폭과 높이 주소를 통해 지뢰 소탕 지역과 지뢰 개수가 인쇄되고 측벽과 지뢰를 보다 직관적으로 구분할 수 있다.

다음으로 Lei를 표시하는 방법에 대해 알아보겠습니다. WinProc 에서 GetDC 함수가 보인다고 가정하면 (스택을 통해 메시지 콜백 함수로 역추적) 대략적으로 Bitblt가 사용될 것으로 추측됩니다 . OD 에서 식을 입력합니다. ctrl+g 다음에 " BitBlt "를 입력하고 F2를 눌러 중단점을 설정하고 지뢰 제거 영역의 아무 위치나 클릭하면 OD가 BitBlt 위치 에서 중단됩니다 .

BitBlt 에도 BitBlt 함수가 있는데 이중버퍼링을 사용해서 그린다는게 예비판단입니다.

BitBlt(hDestDC,// Destination DC XDest, // Destination x 좌표 YDest, // Destination y 좌표 10, // 10, // 다시 그리기 영역의 높이 및 너비 hSrcDC, // Source DC 0, 0, SRCCOPY); / / 광산의 좌표를 계산하는 작업 방법을 지정합니다(좌표를 보려면 첫 번째 지뢰 제거 사각형을 클릭). 아래 그림과 같이 측벽에 주의해야 합니다.







 

측면 벽의 값을 뺍니다.

-0x04=0x0C(12)-0x10(16)

0x27=0x37(55)-0x10(16)

좌표 공식을 구합니다: x ( XDest:12 ) =1*0x10(16)-0x04(4) , y ( YDest:55 ) =1*0x10(16)+0x27(39).

코드 작성

위의 대략적인 분석을 통해 코드를 작성할 수 있으며,





 





 

성취





 

지뢰를 얻기 위해 3개의 지뢰 위치를 입력하십시오 ( 10 벽, 8F 지뢰, 0F 지뢰 없음)





 

2를 입력하여 자동으로 지뢰 제거, 지뢰 표시 및 지도 열기





 

이 작은 프로젝트를 통해 우선 소프트웨어에 대한 일종의 역발상이 강화되었습니다. 생성 된 후 동적 디버깅을 통해 구현 방법 (개발자의 구현 아이디어)을 이해할 수 있으며 키 기본 주소를 찾을 수 있으며 여러 상태 (천둥, 천둥, 벽 없음), 마지막 코딩 단계에서 이해할 수 있습니다 메모리 작업, 몇 가지 중요한 API, 핸들을 얻기 위한 FindWindow , OpenProcess 핸들 열고, ReadProcessMemory가 메모리 정보를 읽고, PostMessage 비동기 메시지 모드, CloseHandle이 핸들을 닫습니다. 일부 분석이 잘못되었거나 제자리에 있지 않습니다. 벽돌을 찾으십시오. 반대로, 코드 분석은 매우 유용합니다. 생각과 프로그래밍 및 테스트 수준을 넓힐 수 있을 뿐만 아니라 프로그램의 허점을 발견, 개발 및 활용하거나 프로그램을 패치하는 등의 작업을 수행할 수 있습니다. 친구들이 이 길고 고된 여정에서 열심히 일하고 서로를 격려하기를 바랍니다.

{{o.이름}}
{{이름}}

추천

출처my.oschina.net/u/4090830/blog/8590989