naroSEC
article thumbnail

개요

 

치트 엔진을 이용한 동적 메모리 값을 변조하는 방법

개요 게임 관련 애플리케이션을 대상으로 코드 분석 및 변조 시 가장 많이 활용되는 도구를 뽑으라고 한다면 치트 엔진(Cheat Engine)이 아닐까 싶다. 치트 엔진은 보통 게임의 메모리 주소를 조작

naro-security.tistory.com

이전 "치트 엔진을 이용한 동적 메모리 값을 변조하는 방법" 포스팅에서는 "어썰트 큐브" 게임을 대상으로 동적 메모리 값을 변조하는 방법을 살펴봤다. 동적 메모리의 경우 프로그램이 실행되는 동안 데이터를 저장하고 처리하기 위해 게임 엔진에 의해 할당되는 메모리로 프로그램이 재실행 될 때 마다 주소가 변경된다. 반면, 정적 메모리는 동적 메모리와 반대로 고정적인 주소를 가지며, 이를 통해 프로그램 내부의 포인터로 직접 참조가 가능해진다. 때문에, 프로그램 재실행 여부와 상관 없이 정적 메모리 주소만 알고 있다면 사용자가 원하는 포인터로 직접 액세스가 가능해진다.

이번 포스팅에서는 치트 엔진을 통해 이러한 정적 메모리 주소를 찾는 방법과 또, 이를 변조하는 방법을 다뤄보도록 하겠다.


실습 준비

치트 엔진 다운로드

 

Cheat Engine

Cheat Engine Trouble installing/running Cheat Engine? Check out the known github issue here on how to solve it, or join the cheat engine patreon Read before download: You must be 18 years or older, or deemed an adult, to install Cheat Engine. Cheat engine

www.cheatengine.org

 

어썰트 큐브 다운로드

 

AssaultCube

What is AssaultCube? AssaultCube is a FREE, multiplayer, first-person shooter game, based on the CUBE engine. Taking place in realistic environments, with fast, arcade gameplay, it's addictive and fun! With efficient bandwidth usage, it's low-latency and c

assault.cubers.net

 

치트 엔진 및 어썰트 게임에 관한 자세한 사용 방법은 이전 포스팅을 참고바란다.


실습

먼저 어썰트 큐브를 실행하고 봇전으로 진입해준다.

[그림 1] 어썰트 큐브 봇전 화면

치트 엔진을 실행하여 어썰트 큐브 프로세스를 어태치 해준다.

[그림 2] 치트 엔진 실행 화면

이번 포스팅에서도 이전 포스팅과 동일하게 캐릭터의 체력(HP)를 타겟으로 정적 메모리 값을 찾을 것이다. 먼저 동적 메모리 주소를 찾아준다. 동적 메모리 값을 찾는 방법을 모른다면 이전 포스팅을 참고하자.

[그림 3] 캐릭터 체력(HP)에 해당하는 동적 메모리 주소

찾은 동적 메모리 주소를 클릭하고 마우스 오른 쪽 버튼을 클릭한 다음 "Find out what accesses this address" 버튼을 클릭해준다. 해당 기능의 경우 어태치하고 있는 프로그램을 디버깅하여 대상의 메모리 주소에 액세스하는 명령어 또는 코드를 찾을 때 사용한다.

[그림 4] Find out what accesses this address 버튼 클릭

[그림 5]와 같이 디버깅 관련 알림 팝업이 출력되는데 "YES"를 클릭해준다.

[그림 5] 치트 엔진을 대상 프로세스에 디버깅 하겠는가에 관한 질문

그러면 [그림 6]과 같이 화면이 출력되며, 출력된 정보가 바로 캐릭터 체력에 관한 데이터 구조체 정보이다. 여기서 캐릭터의 체력을 소모시키거나 증감시키면 해당 주소로 액세스하는 다른 주소 정보가 기록되는데 기록이 다 되면 하단의 stop 버튼을 클릭해준다. 

[그림 6] 캐릭터 체력에 관한 구조체 정보

필자의 경우 캐릭터의 체력을 소모시켰으며, [그림 7]과 같이 sub 연산자와 관련된 메모리 주소가 액세스된 것을 볼 수 있다. 참고로 sub연산자는 두 값을 뺄셈하는 연산을 수행하는 명령어이다.

[그림 7]

그리고 기록된 메모리 주소를 클릭하면 팝업 창 하단에서 메모리 시작 주소인 ESI 값을 확인할 수 있으며, 해당 주소가 바로 플레이어 캐릭터의 구조체를 가르키는 주소이다.

[그림 8] ESI 주소 확인

다시 메인 화면으로 돌아와서 "Memory View" 버튼을 클릭해준다.

[그림 9] Memory View 클릭

상단의 "Tools" 탭을 클릭한 다음 "Dissect data/structures" 버튼을 클릭해준다.

[그림 10] 데이터 구조 분석

"Group1" 입력 폼에 [그림 8]에서 확인한 플레이어 캐릭터 구조체 주소(ESI)를 입력해주고 상단의 "Structures" 탭을 클릭한 다음 "Define new structure" 버튼을 클릭해준다.

[그림 11]

"Structur Name"에는 임의의 문자열을 입력하고 메모리 사이즈는 4096으로 지정 후 "OK" 버튼을 클릭해준다.

[그림 12]

그러면 "Group 1"에 지정한 ESI 주소 즉, 플레이어 캐릭터 구조체 정보를 확인할 수 있으며, [그림 13]과 같이 캐릭터 체력을 가리키는 "0xF8" offset 값도 확인이 가능하다.

[그림 13] 캐릭터 체력에 해당하는 offset 확인

 

이제 체력에 해당하는 실제 데이터 offset 값을 확인했으니 치트 엔진에서 플레이어 캐릭터 구조체 주소(ESI)를 찾음 다음 해당 주소에 0xF8 만큼의 offset 값을 더해주면, 캐릭터의 체력을 가르키는 실제 포인터 값을 찾을 수 있게 된다. "New Scan" 버튼을 클릭하여 새로운 메모리를 스캔해준다.

[그림 14] New Scan 클릭

Hex를 체크해주고 플레이어 캐릭터 주소(ESI)를 입력한 다음에 "First Scan" 버튼을 클릭해준다.

[그림 15] Hex 값으로 새로운 메모리 스캔

[그림 16]과 같이 플레이어 캐릭터 구조체 주소(ESI)를 가르키는 3개의 베이스 주소를 확인할 수 있으며, 이 중 하나를 더블 클릭하여 메모리 테이블에 추가해준다.

[그림 16] 베이스 주소 더블 클릭

메모리 테이블에 추가된 주소를 더블 클릭하면 [그림 17]과 같이 메모리 주소 변경 관련 팝업이 출력되는데 여기서 Address를 복사해준다.

[그림 17] 메모리 주소 복사

① Pointer를 체크 후 ②에 복사한 주소를 붙여넣기 하고 ③에 [그림 13]에서 확인한 offset 값을 입력한 다음 ④ Hexadecimal를 체크해제 하여 값을 10진수로 출력되게끔 해준다.

[그림 18]

모든 과정이 끝났다면 [그림 19]와 같이 캐릭터의 체력 값을 가리키는 포인터 주소 즉, 정적 메모리 주소를 획득할 수 있게 된다. 해당 주소는 게임이 재실행 되어도 변하지 않으며, 따로 저장하고 있다가 불러오기 기능을 통해 해당 값에 바로 액세스 할 수 있게 된다. 추후 포스팅에서도 설명하겠지만 지금 이와 같은 방법은 게임 핵을 만들 때도 사용되는 방법 중 하나이다.

[그림 19] 정적 메모리 주소 획득


마무리

지금까지 어썰트 큐브 게임을 대상으로 정적 메모리 주소를 획득하는 방법을 살펴봤다. 변조를 하고자 하는 대상 주소를 가르키는 정적 메모리 주소만 획득할 수 있다면, 게임이 재시작 되어도 일일히 다시 메모리 주소를 찾을 필요가 없어 굉장히 편하다. 그리고 해당 방법은 실제 게임 핵 제작 시 사용되는 방법 중 하나이며, 추후 포스팅에서 게임 핵을 만들 때도 사용할 예정이다. 다음 포스팅에서는 치트 엔진을 이용한 코드 인젝션을 살펴보도록 하겠다.

profile

naroSEC

@naroSEC

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

profile on loading

Loading...