이제 실제 게임 상황에서 점수가 어떻게 오르는지, 피카츄와 공의 접촉은 어떻게 처리되는지를 살펴보고자 합니다. 우선 점수부터 확인합시다. 아마 어떤 변수에 게임 스코어가 기록이 되어있을테고 땅에 공이 접촉하는순간 스코어가 증가할테니 우선 그 변수의 주소부터 찾아봅시다. 찾기 위해 사용한 프로그램은 Cheat Engine입니다. 비록 치트엔진이 살짝 툴키디들이 쓸 것만 같은 느낌이 있지만, 간단한 프로그램내의 메모리를 뒤질 때에는 정말 유용하다고 생각합니다.
순식간에 2개로 걸러졌네요. 5:0까지 가보면 0x2823CFC가 왼쪽의 점수를 담는 메모리 주소임을 알 수 있습니다. 점수를 담는 메모리는 알아냈고, Find out what writes to this address(F6)으로 이 메모리에 어떤식으로 쓰는지를 확인해보면
잡아냈습니다. 0x403CAE에서 사용하네요. 저 부근에 많은 것이 있길 바라며 ollydbg에서 저 곳으로 가보겠습니다. 403CAE에서 breakpoint를 걸어두고 게임을 진행하다보면 점수가 나는 상황(공이 지면에 닿은 상황)에서 멈춥니다. 0x2823CFC의 값을 1 증가시키고, 정황상 이게 1P의 점수겠네요. 그리고 2P가 점수를 내는 상황에서는
실제로 코드를 패치하고 실행하면 공이 어디에 떨어지더라도 오른쪽의 점수만 올라갑니다. 참고로 이건 1P 모드로 하던, 2P 모드로 하던 동일하게 들어오는 루틴입니다. 아래는 오른쪽의 점수만 올라가게 변경한 바이너리의 시연 gif입니다.
그런데 지금 생각해보면 이미 eax에 0 혹은 1이 담겨져왔고, 그렇다는 의미는 승패 판정을 이전에 끝냈다는 의미입니다. eax에 담겨있다는 것은 정황상 함수의 리턴값일 확률이 크니 코드를 다시 살펴봅시다. sub_402D90에 ESP+20(=0x19FDF8)을 인자로 보내고, 함수를 거친 후에 [ESP+20]의 값이 0xD8보다 작거나 같을 경우 1(2P 승), 0xD8보다 클 경우 0(1P 승)이 됩니다. 뭔가 직관적으로 [ESP+20]이 공의 x 좌표일 것 같다는 생각이 듭니다. 그런데 sub_402D90에 들어가기 전의 상황을 확인해보면 아직 ESP+20(=0x19FDF8)번지에 0xD8에 근접한 값이 들어가있지 않습니다. 그렇다면 sub_402D90에서 인자로 0x19FDF8번지를 넘겨받아 그 번지에 공의 x좌표 값을 넣는 것으로 추정할 수 있겠습니다. sub_4D2D90은 아래와 같이 생겼습니다.
인자가 NULL pointer인지 체크하고(TEST EDI, EDI) 그렇지 않다면 [EAX+30](0x41D61E0)부터 5개의 int의 값을 인자의 주소에 넣습니다.(느낌상 공의 구조체일 수 있겠다는 생각이 듭니다.) 그러니까 예를 들어
이렇게 41D61E0부터 int 5개의 값이 0x174, 0xFC, 0x4, 0xFFFFFFEF, 0x20이었을 경우, 0x402DAB를 수행하고 나면 0x19FDF8부터 int 5개의 값이 동일하게 바뀝니다.
sub_4031B0은 되게 분석하기 싫게 생겼네요. 일단 넘어갑시다.
sub_403DD0의 return값이 0이면 공의 x좌표를 검사하는 루틴을 건너뛰고 1이면 공의 x좌표를 검사한 후 1P 혹은 2P의 점수값을 1 증가합니다. 그리고 F9로 계속 run을 해보면 매 프레임마다 0x403C70에 break가 걸림을 알 수 있습니다. 그러면 sub_403DD0이 공이 바닥에 닿았는가를 판단하는 함수일 것으로 추정할 수 있습니다. 다음 글에 이어서! |
'컴퓨터과학 > 리버싱' 카테고리의 다른 글
[피카츄배구 리버싱] 최종 (8) | 2018.03.11 |
---|---|
[피카츄배구 리버싱] 8 (0) | 2018.03.11 |
[피카츄배구 리버싱] 7 (0) | 2018.03.11 |
[피카츄배구 리버싱] 5 (0) | 2018.03.11 |
[피카츄배구 리버싱] 4 (0) | 2018.03.10 |
[피카츄배구 리버싱] 3 (0) | 2018.03.10 |