1. 지난 글에서 했었던 명령어와 디버깅을 기억합시다.
이제는 앞의 Step 1과 Step 2에서 쓰던 기초적인 Value 변화에 따른 스캔은 따로
과정에 올리지 않을 예정입니다. 글이 너무 길어지기도 하고 초반에 한 두번 보면
바로 이해할 수 있을 정도라고 생각하기 때문에 스킵해도 되는 것은 과감히 스킵하죠.
우선 gtutorial 과 치트엔진을 켜주시고 Step 3번에 맞춰봅시다.
빨간색으로 된 받침들을 다 초록색으로 만들면 우측 문이 열린다는 뜻인거 같네요.
주의할 점은 저 가시 모양이 좌우로 움직이는데 이에 닿으면 바로 죽는다는 것 같고.
힌트는 결국 해결할 수 있는 방안을 제시해놓은거로 보입니다.
충돌해도 안 죽게끔 설정하든가 텔레포트를 하든가 날아가서 하든가 < 라고 되있네요.
뭐 힌트 말대로 이 문제를 해결할 수 있는 방법 자체는 여러가지로 보입니다.
제 생각에는 텔레포트나 날아다니는거 쪽으로 초점을 맞춰보는게 나을거 같아요.
우선 텔레포트를 하려면 플레이어 캐릭의 좌표가 있어야 할 것입니다.
이 좌표를 구하려면 멈춰 있는 상태로 Unknown 스캔을 하고 그 상태에서
움직이면서 Changed Value를, 안 움직일때 Unchanged Value를 반복으로
재스캔 하시면서 찾는게 제일 무난한 방법으로 보입니다. 한 번 찾아봅시다.
대충 줄여봤을때 이 정도가 한계인거 같습니다.
이 경우 2,3,4번째 주소를 배제한다고 해도 나머지 보이는 주소들이 전부 Value가 같은 상황입니다.
이러면 어쩔수 없이 하나하나 확인을 해볼 수 밖에 없는데, 우선 첫번째 주소인 0157CB34를 내려서 프로즌 해봅시다.
프로즌은 전 글에서 설명했듯이 Active에 체크를 누르면 고정이 됩니다.
고정을 할 경우 플레이어의 캐릭터가 양 옆으로 움직여지지 않는것을 확인할 수 있습니다.
그러면 이게 X축 좌표를 담는 주소인거고 찾았습니다. 그런데 높이를 의미하는 Y는 어디 있을까요?
이 프로그램의 경우에는 X축 좌표를 찾을때처럼 세팅해놓고 Step 3 그림에서 보면 P를 누르면 멈춥니다.
이 멈춤 현상을 이용해서 천천히 떨어지는거를 Changed, Unchanged 반복을 하면 찾을 수 있을겁니다.
근데 그전에 메모리뷰를 열어보도록 하죠.
위에서 기술했듯이 0157CB34는 X, 즉 좌우에 대한 좌표값이었습니다.
그런데 오른쪽을 보시면 제 캐릭이 살짝 공중에 떠 있는 상태이므로 Y가 땅바닥에 있을때와는 다른 값을 지닐텐데
X 옆을 보시면 빨간색 표시로 돼있습니다. 이 빨간색 표시는 기존의 값에서 변하고 있다는걸 가시적으로 표현해줘요.
그 말은 즉 X 좌표가 담긴 주소에서 +4를 하게 되면 Y 좌표인게 됩니다.
0157CB34 = X좌표
0157CB38 = Y좌표
이렇게 되는것이죠.
우선 이런식으로 Float 형으로 타입을 교체하고 2개를 추가해둡니다.
그리고 0157CB34에 Find out access를 걸어두고 왼쪽으로 계속 이동을 해봅니다.
Count 가 475와 1425는 내가 움직이든 안 움직이든 내 좌표를 계속 읽어서 표시를 해주기 위해
이 좌표에 접근하는 곳의 명령어들이라고 보면 이해가 좀 편하실겁니다. 그러면 이 부분은 당연히
움직이는데에 직접적으로 변화를 줄 때 사용하는 곳이 아니니까 저희가 볼 곳은 아닌거죠.
그러면 밑에 Count가 145인 것과 97인 것을 봐야합니다.
145인건 말 그대로 왼쪽으로 움직일 때 Float Value를 보시면 음수쪽으로 계속 증가하는걸 볼 수 있습니다.
그러다가 -0.97부터 증가를 하지 않습니다. 즉 증가를 못하게끔 막고 있다는건데 Count 97인 명령어가
그 증가를 못하게 막고 있다고 보면은 될거 같으니까 우선 저 부분을 봅시다.
gtutorial-x86_64.exe+4126D - F3 0F5E 05 53662700 - divss xmm0,[gtutorial-x86_64.exe+2B78C8] { (2.00) }
gtutorial-x86_64.exe+41275 - F3 0F58 05 43672700 - addss xmm0,[gtutorial-x86_64.exe+2B79C0] { (-1.00) }
gtutorial-x86_64.exe+4127D - 0F2F 47 24 - comiss xmm0,[rdi+24]
gtutorial-x86_64.exe+41281 - 7A 2D - jp gtutorial-x86_64.exe+412B0
gtutorial-x86_64.exe+41283 - 76 2B - jna gtutorial-x86_64.exe+412B0
gtutorial-x86_64.exe+41285 - 48 8B 4B 28 - mov rcx,[rbx+28]
gtutorial-x86_64.exe+41289 - 48 8B 43 28 - mov rax,[rbx+28]
gtutorial-x86_64.exe+4128D - 48 8B 00 - mov rax,[rax]
gtutorial-x86_64.exe+41290 - FF 90 D0000000 - call qword ptr [rax+000000D0]
gtutorial-x86_64.exe+41296 - F3 0F5E 05 2A662700 - divss xmm0,[gtutorial-x86_64.exe+2B78C8] { (2.00) }
gtutorial-x86_64.exe+4129E - F3 0F58 05 1A672700 - addss xmm0,[gtutorial-x86_64.exe+2B79C0] { (-1.00) }
gtutorial-x86_64.exe+412A6 - 48 8B 43 28 - mov rax,[rbx+28]
gtutorial-x86_64.exe+412AA - F3 0F11 40 24 - movss [rax+24],xmm0 < 이 부분이 Find out access로 나온 곳
이 부분에서 저희가 봐야할 것은 comiss xmm0,[rdi+24] 와 밑의 조건문입니다.
저 조건문을 통과하지 않았을 때 저희가 Find out access로 찾은 곳이 지나가기 때문이죠.
comiss 명령어의 경우 cmp와 동일한데 실수 형태 비교를 할 때 쓰는 명령어입니다.
xmm0 역시 실수를 다루기 위해 쓰는 레지스터입니다. 그렇게 알고 넘어가시면 됩니다.
그러면 xmm0 과 rdi+24의 Value를 비교한다는건데 rdi+24는 대충 플레이어의 X 좌표인걸 알겠는데
xmm0의 값은 어디서 볼까요? 그걸 알아야 이해가 편할꺼 같은데 말입니다.
이 부분에다가 F5로 디버깅을 걸어봅시다.
아마 좌표 비교구간이라 별다른 행위를 하지 않더라도 바로 디버깅이 걸릴겁니다.
걸리고 난 뒤에 우측 중간에 보면 > 라고 화살표 모양 보이실거에요. 눌러봅니다.
이러면 이제 디버깅 걸린 상태에서의 실수 레지스터들이 담고 있는 값들을 보실 수 있습니다.
-0.97이면 아까 위에서도 -0.97 증가하지 않는걸 확인 했었죠? 그러면 jna 조건문이 이해가 될 것입니다.
'-0.97보다 크지 않으면 점프해라' 이 의미가 되는거잖아요?
맨 왼쪽이나 맨 오른쪽에 붙어있으면 -0.97로 동일해지기에 점프를 안하고 밑의 명령어를 실행하는 것입니다.
그러면 여기서 플레이어가 움직일 수 있는 X 좌표의 크기는 -0.97 ~ 0.97 로 한정적이다. 라는 것을 확인 했습니다.
Y의 경우 점프를 안하고 가만히 있을 경우 0.875로 고정이 되어 있는데
점프를 할 경우 수치가 낮아지는걸 확인 할 수 있었습니다. X와 비슷한 논리로 구성되있을거라 생각하고 보면
플레이어가 움직일 수 있는 Y 좌표의 크기는 -0.875 ~ 0.875 로 한정적이다. 라는 것을 짐작 할 수 있죠.
자 그러면 범위는 알아냈으니 이제 저 수치들을 조정하면서 발판을 하나하나 눌러보도록 하죠.
ㅋㅋㅋㅋ... 이렇게 텔레포트로 발판을 다 누르니까 문을 막아버리네요...?
하지만 상관 없습니다. 우리는 저 맨 끝 좌표가 뭔지를 알고 있기 때문에요.
맨 밑으로 내려간 상태에서 X 좌표가 담긴 주소를 0.97로 변경해봅시다.
예.. 뭐 막아버려도 소용 없죠. 이미 좌표를 알아버린 이상
저 문의 좌표로 텔레포트를 해버리면 그만인거니까요... 이렇게 Step 3 도 끝냈습니다.
well done 메시지박스를 끄니까 메시지박스가 하나 더 뜨네요.
당신은 3개의 게임을 이겼고 무결성 검사를 통과했다... 정말 잘했다..
이게 Step이 3개가 끝인가보네요. 이러면 gtutorial을 완료 했다고 볼 수 있습니다.
다음 글은 간단한 응용 + 다른 방법으로 해결을 써보겠습니다.
'Reversing & Cheat Engine' 카테고리의 다른 글
9. 크랙미 첫 번째 (0) | 2024.02.23 |
---|---|
8. API 함수를 통한 리버싱 & 크랙 (0) | 2024.02.22 |
6. 어셈 명령어 (0) | 2024.02.19 |
5. 어셈블리어 (0) | 2024.02.19 |
4. 치엔 게임 튜토리얼 Step 2 (2) | 2024.02.19 |