1. 질문
9단계: 코드 공유: (PW=31337157)
이 단계에서는 같은 유형의 다른 오브젝트에 사용되는 코드를 처리하는 방법을 설명합니다.
종종 유닛이나 내 플레이어의 생명력을 발견했을 때 코드를 제거하면 적에게도 영향을 미치는 것을 발견할 수 있습니다.
이런 경우 내 오브젝트와 적 오브젝트를 구별하는 방법을 찾아야 합니다.
플레이어의 고유 위치를 가리키는 첫 4바이트(함수 포인터 테이블)를 확인하는 것만큼 쉬운 경우도 있고, 팀 번호나 플레이어 이름에 대한 포인터에 대한 포인터를 가리키는 포인터를 확인하는 것만큼 쉬운 경우도 있습니다. 이 모든 것은 게임의 복잡성과 운에 따라 달라집니다.
가장 쉬운 방법은 찾은 코드가 어떤 주소에 쓰는지 찾은 다음 데이터 분석 기능을 사용하여 두 구조를 비교하는 것입니다. (내 유닛/플레이어와 적) 그런 다음 이들을 구별할 수 있는 방법을 찾을 수 있는지 알아보세요.
나와 컴퓨터를 구별하는 방법을 찾았다면 조건을 검사하는 어셈블러 스크립트를 삽입한 다음 코드를 실행하지 않거나 다른 작업을 수행할 수 있습니다. (예를 들어 원 히트 킬)
또는 이를 사용하여 검색에 사용할 수 있는 “바이트 배열”이라는 문자열을 생성하여 자신 또는 적 플레이어의 모든 목록을 생성할 수도 있습니다.
이 튜토리얼 에서는 가장 놀라운 게임을 구현해 보았습니다.
플레이어가 4명입니다. 2명의 플레이어는 팀에 속하고 2명의 플레이어는 컴퓨터에 속합니다.
여러분의 임무는 체력을 기록하는 코드를 찾아서 체력을 얼리지 않고 게임에서 승리하도록 만드는 것입니다.
계속하려면 “게임 다시 시작 및 자동 플레이”를 눌러 코드가 올바른지 테스트합니다.
팁: 체력은 유동적입니다
팁2: 여러 가지 해결책이 있습니다.
2. 분석 과정
오른쪽은 봇 플레이어, 왼쪽은 사용자 플레이어인데, 우리팀 체력이 0이 되기전에 봇 플레이어 체력을 모두 없애야 다음 튜토리얼로 넘어갈 수 있다.
그런데 다음과 같은 문제점이 있다.
- 우리 팀의 체력이 상대팀에 비해 1/5로 적다.
- 공격 시 체력이 깎이는 양이 6~1 vs 1로 우리 팀의 공격력이 약하다.
그렇다면 우리 팀이 이기기 위해서는 어떻게 해야 할까?다음과 같은 방법이 있을 것이다,
1. 우리 팀의 체력을 높이거나 상대팀의 체력을 낮추기
2. 우리팀의 공격력을 높이거나 상대팀의 공격력을 낮추기
우리팀의 체력 코드를 수정하여 step9를 통과해보자
4byte로는 검색결과가 나오지 않아 value type을 all로 지정한 뒤 체력을 검색하여 값이 바뀌는 변수를 추적한다.
더블클릭하여 주소목록에 추가한 뒤, 해당 주소에 접근하는 목록을 확인한다.
해당 창을 켜둔 채로 다시 주소목록에서 오른쪽 버튼 – Browse this memory region 클릭한다
Browse this memeory region 기능은 주소에 따른 메모리 영역의 값을 바이트 단위로 확인할 수 있게 한다.
해당 변수의 위치와 float 값, 그리고 플레이어이름인 dave를 확인할 수 있다.
초록색으로 마크된 부분의 42B60000 은 float 형식 91.00을 hex 값으로 변환했을 때의 값이다.
그렇다면 이 값을 크게 수정하기만 하면 우리 팀이 이기도록 할 수 있을까? 가령 5000 정도로 큰 값을 준다면 이길 수 있을 것이다.
5000을 hex 값으로 변환하면 0x459c4000 이다. 이값을 입력해 보자
초록 부분을 더블클릭하면 값을 수정할 수 있다.
수정하고 나서, autoplay를 눌러보니 또 우리 팀의 체력이 모두 소진되어지고 말았다.
왜 이런 일이 일어났을까?
그 이유는 해당 체력을 저장하는 주소가 static 하지 않기 때문이다. 이전 포인터 과제처럼 우리는 고정된 포인터 주소를 찾아 값을 freeze 시켜주어야한다.
다시 시작해본다. Tutorial 6,8과과 비슷하게 진행된다.
먼저 dave 변수를 찾아 주소목록에 추가한다.
Dave 의 체력을 저장하고 있는 주소는 093A8338 이다. 이 주소에 접근하는 목록을 확인한다.
Movss [rbx+08], xmm0 : Xmm0 값을 rbx값에 오프셋 8 만큼 더한 주소에 저장한다.
[rbx+08] 는 093A8338 = dave의의 체력이 저장된 변수의 주소이다.
이 변수의 포인터를 찾기위해 rbx 값인 093 A8330을 스캔해야 한다.
검색하니 해당 주소를 참조하는 변수가 세 개나 나왔다. 모두 주소목록에 추가한다.
어느 것이 우리가 찾는 변수의 포인터인지 확인을 위해서는 “Find out what accesses this address” 메뉴를 사용하여 attack 버튼을 누르면서 해당 주소에 접근하는 목록이 검출되는지 본다.
첫 번째 주소만이 목록이 검출되었고 나머지는 아무것도 잡히는 게 없었다. 나머지를 주소목록에서 제거한다.
Mov rcx, [rbx+00000888] : rbx(00125B40)에 888을 더한 주소에 저장된 값을 rcx에 저장
rbx값인 00125B40을 검색한다.
목록이 길지만 아래로 내려보면 녹색의 주소를 확인할 수 있다. 바로 이 주소가 포인터의 시작점이다.
더블클릭하여 주소목록에 추가한다.
다음, Add address Manually 버튼을 클릭하여 지금까지 거쳐왔던 offset값을 입력한다.
상단의 424C0000은 hex값으로 float형식으로 변환하면 현재 dave의 health 값인 51과 일치한다.
추가한 포인터의 value를 더블클릭하여 값을 수정해준다. 461c4000은 float값으로 변환하면 10000이다.
값을 바꾸어줬다면, acitve에 체크하여 값을 고정시킨다.
Restart game and autoplay를 클릭하여 게임을 실행해 본다.
Dave의 health 값이 남아 우리 팀이 승리하게 된다.
기본 튜토리얼은 이렇게 마무리가 되었다.
다음 단계부터는 cheat engine에서에서 제공하는 플레이 가능한 게임을 이용하여 튜토리얼이 진행된다.