본문으로 바로가기

파일의 IT 블로그

  1. Home
  2. 보안 강좌/CheatEngine
  3. [Cheat Engine] 치트엔진 튜토리얼 #5 풀이

[Cheat Engine] 치트엔진 튜토리얼 #5 풀이

· 댓글개 · KRFile

글을 읽기 전 알고 있으면 좋은 내용

- 컴퓨터 구조 (대학교 2학년 전공자 수준)

 

 

5단계: 코드 검색기 (PW=888899)
가끔은 값의 위치가 게임을 다시 시작하거나 게임을 플레이하는 동안에도 변경될 수 있습니다. 이 경우에는 테이블을 계속 작동하도록 하는 데 사용할 수 있는 두 가지가 방법이 있습니다. 이번 단계에서는 코드 검색기 기능을 사용하는 방법에 대해 설명하겠습니다.

아래 값은 각각 튜토리얼을 실행할 때마다 다른 위치에 있을 것입니다. 따라서 address list의 일반 항목으로는 작동하지 않을 것입니다.

먼저 주소를 찾아보세요. (이제 이 단계까지 왔으므로 찾는 방법을 알고 있다고 가정합니다.)

주소를 찾았으면, Cheat Engine에서 해당 주소를 마우스 오른쪽 버튼으로 클릭하고 "Find out what writes to this address"를 선택하세요. 그러면 비어있는 목록이 있는 창이 열립니다.

그런 다음, 이 튜토리얼에서 값을 변경 버튼을 클릭하고 Cheat Engine로 돌아가세요. 모든 것이 제대로 실행되면, 어셈블러 코드가 있는 주소가 있을 것입니다.

그 주소를 클릭하고 Replace 옵션을 선택하여 아무것도 하지 않는 코드로 대체하세요. 그러면 Advanced Options 창의 코드 목록에도 코드 주소가 추가됩니다. (테이블을 저장하면 저장됩니다.)

정지를 클릭하여 게임이 정상적으로 실행되도록 하고 창을 닫으세요.

이제 값 변경 버튼을 클릭하면 모든 것이 제대로 실행되었다면 다음 버튼이 활성화됩니다.

참고: 주소를 충분한 속도로 고정하면 Next 버튼이 어떤 경우에는 이미 표시될 수도 있습니다.

 

이번 문제는 튜토리얼 안의 설명글을 읽어도 이해하기가 좀 어려우실겁니다. 일단 기본적으로 비전공자 수준에서 싱글 게임 치트 정도의 값 찾기는 앞에서 배운 튜토리얼 4번까지의 지식 정도만 가지고도 충분히 할 수 있습니다. 개인적으로 간단한 게임 치트 정도가 목적이신 분들은 4단계까지만 풀어보시고 멈춘다음에 직접 실습해보시는게 좋을 듯 합니다. (당연하지만 온라인 게임에서 하면 고소먹으니깐 조용히 혼자 즐기는데만 사용하시구요..)

 

제 튜토리얼의 목적은 어디까지나 정확한 "이해" 입니다. 정확한 이론적 지식 없이 문제 풀이만 집중해서는 공부하는 의미가 크게 없으니깐요..! 여기 5편 이후로부터는 어느정도 컴퓨터 구조에 대한 이해와 지식을 기반으로 문제풀이를 진행합니다. 제 글로 이해가 어려우신 분들은 인터넷에 많은 분들이 치트엔진 튜토리얼 관련해서 좋은 글들을 작성해주셨으니 그걸 참고해주시면 되겠구요.

 

일단은 제가 글마다 "글을 읽기 전 알고 있으면 좋은 내용" 이라고 링크 걸어둔 글들을 웬만해서 한번쯤은 꼭 읽어보시길 바랍니다. 물론 글마다 대부분 다시 설명하긴 하는데 다시 대략적으로 설명하는것들이라 원래 썼던 이론글들 보다 정확도가 떨어질 가능성이 높습니다.

 

어쨌던 간에 이번 문제는 저 Change Value라는 버튼을 눌렀을때 위에 100이라는 숫자가 랜덤하게 변화하는데 저걸 눌러도 더 이상 값이 변하지 않게 하는게 오늘의 목적입니다.

 

 

이론 설명

지겹게 봤던 그림입니다. 파워포인트로 한번 그려놓고 계속해서 우려먹으니깐 아주 기분이 좋네요.

지금까지 우리가 치트엔진으로 작업했던 것은 한 가지 진리때문인데 바로 "현대 컴퓨터 구조에 의해 모든 프로그램은 RAM위에 올라와서 실행된다!" 였습니다. 그리고 우리는 치트엔진으로 RAM 데이터에 접근해서 데이터를 변조할 수 있었죠.

 

그러나. 여기서 또 한가지 중요한 핵심이 있는데 결론적으로 RAM위에 올라와서 실행될 수 있었던 이유는. 우리가 더블클릭해서 실행한 실행파일(*.exe)이 RAM위에 기계어로 올라온 뒤에 바로 "CPU" 가 실행하기 때문이였습니다.

 

사실 결론적으로 RAM위에서 명령어를 읽어서 실행하는것도, RAM에 무언가 데이터를 저장하는 것도 전부 CPU가 있기에 가능한 일입니다. CPU가 중앙처리장치라는 이름 그대로 컴퓨터 동작의 대부분의 일들을 총괄하니깐요.

RAM에서 프로그램 명령어를 읽거나 데이터를 저장하는 건 CPU가 합니다.

 

위에 사진에 빨간 네모를 보시면 알겠지만 우리가 치트엔진으로 조작한 부분은 바로 저기 RAM에 있는 데이터 부분입니다.

 

 

 

우선은 추정컨데, 저 100이라는 값은 RAM에 저장되고 있을것입니다. 지금까지 앞에서 이해한 바로는 그렇죠? 그러나 Change value를 누르면 저 100이라는 값이 변화하는데 이 값을 변화하게 하는 건 과연 누가할까요?

 

위에 설명드렸다 싶이 RAM에 올라온 프로그램 명령어를 읽는것도, RAM에 데이터를 기록하는것도 CPU가 합니다.

결론적으로 Change value를 누르면 어떤 CPU 명령어가 실행되어 저 100이라는 값이 저장된 RAM의 주소로 가서 값을 바꾸게 됩니다.

 

 

 

이번 문제는 아시다 싶이 change value를 눌러도 위에 숫자값이 바뀌지 않게 해야합니다.

숫자값을 바꾸는 것은 특정 CPU 명령어에 의한 것이므로 이번에는 주황색 네모가 쳐진 CPU 부분에 개입해야 합니다.

 

RAM에 있는 값이 바뀔때마다 원래 값으로 돌려버리는 것도 가능하겠지만 근본적으로는 이 값을 바꾸는 CPU 명령어를 바꿔버려야겠죠.

 

아마도 change value를 누르면 어떤 CPU 명령어가 실행되어 위의 숫자값을 바꿀 것이고, 우리는 이 CPU 명령어를 실행되지 않게 해서 변화를 막아야 합니다.

 

엥? 분명 치트엔진은 메모리 수정 도구라고 들었는데요. CPU 명령어에 개입하는것도 가능한가요? 라고 하면 맞습니다!

치트엔진은 실제로 매우 강력한 도구라서 어떤 메모리 값에 개입하고 있는 CPU 명령어를 찾아내서 바꿔내는게 가능합니다. 이렇게 CPU 명령어에 개입해서 무언가 바꾸거나, 멈추거나 수정하는 프로그램을 디버거라고 표현하기도 하는데 이러한 디버깅 기능을 치트엔진에서 지원합니다.

 

보안 분야를 공부해보신 분들이 알겠지만 이 정도 기능까지 사용하실 수 있게 되면 리버싱 쪽 영역에 가깝습니다. 

 

Solution

[참고*오늘은 64bit 치트엔진 튜토리얼 (Tutorial-x86_64.exe) 이 아닌 32bit 치트엔진 튜토리얼 (cheatengine-i386.exe) 프로그램으로 진행합니다.*]

 

 

일단은 이전에 하던대로 먼저 저 위에 바뀌는 숫자의 메모리 주소값을 찾아야 합니다.

지금 Change value를 시험삼아 눌러대서 그런지 값이 649네요.

 

 

치트엔진 튜토리얼 앞에서 대부분의 윈도우 앱은 정수값 표현시 4바이트를 사용한다고 하였으므로 Exact Value 모드로 4바이트 649를 검색하도록 합시다.

운이 좋게도 값이 한번에 찾아졌네요. 실제로 이런 경우는 거의 없지만 튜토리얼 프로그램이 매우 작아서 그런 거 같습니다 ^^; 지금 값이 485로 바뀌어 있는건 값이 한번에 찾아져서 맞나 확인해보기 위함입니다.

 

 

017F55D0 의 주소에 저장된 값이 바로 치트엔진 튜토리얼에 보이는 저 485라는 값이네요.

그러면 아까도 확인했지만 RAM에 값을 읽거나 쓰는 주체는 CPU 라고 했고, Change value 클릭시 어떤 CPU 명령어가 실행되어서 저 017F55D0 주소에 있는 값이 변경되고 있을겁니다.

 

이 주소에 어떤 CPU 명령어가 개입해서 값이 바뀌고 있는지 궁금하면 Find out what writes to this address를 검색합니다.

위에 what access 라고 비슷한게 보이는데 이건 해당 주소 값을 포인터를 이용하여 바꾸고 있을때 찾는 기능입니다.

포인터는 C언어를 배워보신 분들은 아시겠지만 그 포인터 맞습니다. 변수에 주소값 저장해서 가리켜서 바꾸는 그 기능..

 

어쨌던 지금의 경우 저 값을 특정 CPU 명령어가 "직접" 바꾸고 있으므로 what writes를 선택해야 합니다.

(뒤에서도 배우겠지만 이 값이 포인터로 변경되고 있다고 의심되면 what access 로 접근해야 합니다)

 

 

디버거를 프로세스에 Attach (붙일거냐) 할꺼냐고 물어보는데 Yes를 눌러줍니다.

 

그러면 치트엔진 디버거가 돌아가서 이 메모리 주소에 어떤 cpu 명령어가 영향을 끼치는지 추적이 가능합니다.

추적은 지금부터 시작했으므로 아무것도 안뜰겁니다. 

 

저 메모리 주소값에 변화를 주기 위해 Change value를 다시 눌러줍니다.

 

바꾸자마자 어떤 명령어가 떴습니다. mov [eax], edx 라네요. 아마 어셈블리 명령어를 모르시는 분들은 여기서부턴 외계어에 가까울 겁니다.. 제가 원래는 앞에서 CPU 레지스터 부분까지 설명을 드리려고 했는데 거기까지 하면 이 글 읽다가 나갈 거 같아서 뺐습니다.

 

어쨌던 저 mov [eax], edx 라는 명령어가 어떤 의미를 가지는지 잘 이해하지 못해도 괜찮습니다 ㅋㅋ. 

일단은 저 CPU 명령어 한 줄이 실행되어서 017F55D0 주소 위치의 값을 바꾸고 있다는게 되니깐요.

Change Value를 누르면 저런 명령어가 실행되어서 위에 숫자값을 바꾸나 봅니다.

 

우리의 목적은 알다 싶이 Change Value를 눌러도 위에 숫자값이 바뀌지 않게 하는겁니다.

결론적으로 저 mov [eax], edx 라는 명령어가 실행되지 않게 하면 Change Value를 눌러도 아무 명령어가 실행되지 않아서 값이 절때 바뀌지 않겠죠.

 

일단 저 CPU 명령어 역시 RAM위에서 실행되고 있습니다. Show disassembler를 눌러서 바로 따라가봅시다.

 

보다 싶이.. 우리가 프로그램을 더블클릭하면 RAM위로 올라와서 실행된다고 했는데, 실제로 RAM위로 올라와서 실행되는 기계어들이 다음과 같습니다. 정확히는 왼쪽은 기계어 (16진수) 고 오른쪽은 그걸 쉽게 보기 위한 어셈블리어 입니다.

 

당연하지만 어셈블리어나 기계어 개념을 모르시는 분들한텐 그저 외계어에 가까울 겁니다.

저도 처음에 봤을땐 굉장히 어지러웠거든요..

 

일단 잘 이해가 안되면 mov [eax],edx 가 현재 숫자값을 바꾸는 cpu 명령어다 정도만 이해하고 갑니다.

저걸 아무 의미 없는 아무것도 안하는 명령어로 바꿔야 합니다.

 

mov [eax],edx 를 더블클릭하면 이런 창이 열려서 CPU가 실행하는 명령어를 실시간으로 변경해낼 수 있습니다.

 

우리가 흔히 쓰는 인텔 CPU / AMD CPU를 기준으로 아무것도 하지 않는 어셈블리 명령어는 바로 NOP 입니다.

NOP을 누르고 OK를 누릅니다.

 

뭐라 나오는데 명령어 길이가 안맞아서 자기가 알아서 바이트를 맞추겠다~ 이런의미입니다.

무슨 의미 인지 모르겠으면 그냥 Yes를 누릅니다.

 

보다 싶이 원래 숫자를 바꾸던 명령어를 Nop으로 변경했습니다.

 

이제 프로그램으로 돌아와서 Change Value를 눌러도 위의 값이 미동하지 않는걸 알 수 있습니다.

기존에 램 값을 바꾸는 명령어를 NOP(아무것도 하지않는 명령어) 으로 패치해버렸으니깐요.

어쨌던 성공입니다!

SNS 공유하기
💬 댓글 개
이모티콘창 닫기
울음
안녕
감사해요
당황
피폐

이모티콘을 클릭하면 댓글창에 입력됩니다.