본문 바로가기
리버스 엔지니어링/치트엔진 튜토리얼

[5편] 치트엔진 튜토리얼 - Step 5 (어셈블리어 맛보기)

by leedg 2022. 12. 5.
반응형

치트엔진 튜토리얼 실행

우선 치트엔진 튜토리얼을 하기 위해서, 치트엔진과 튜토리얼 프로그램을 켜보도록 하겠습니다.

치트엔진을 킨 상태에서 Help-> Cheat Engine Tutorial (64-Bit) 클릭

 


치트엔진 튜토리얼 - STEP 5

우선, 아래와 같은 사진의 프로그램이 실행되었다면 Process Attach를 해보도록 하겠습니다.

치트엔진 튜토리얼 화면

 

여러가지 프로세스 중에서 아래 사진과 같이 Tutorial-x86_64 를 Open 해 줍니다.

Process List 화면

STEP 5 설명

Step5는 아래 사진에서 볼 수 있듯이 <100>이라고 써져있는 값이 있습니다 .

이 값은 Change value 버튼을 눌렀을 때 임의의 숫자로 변경됩니다.

Step 5의 미션은 <Change Value>버튼을 눌렀을 때, 숫자가 변경이 안되게 어셈 코드를 수정하는 것 입니다.

(어셈 = 어셈블리어)

치트엔진 튜토리얼 Step 5 화면

 


스텝5는 어셈블리어 코드를 수정하는 과정을 거칩니다.

이 어셈블리어를 간단하게 이해하기 위하여 아래 예제를 통해 설명을 하겠습니다.

 

설명에 앞서, 어셈블리 안에있는 레지스터라는 개념을 아셔야합니다.

 

쉽게 얘기해서 우리가 프로그래밍 언어에서 변수를 선언하면 그 선언한 변수의 자료형만큼의 저장공간이 생깁니다.

그런 저장공간이 어셈블리어에서는 변수선언이 따로 없기 때문에 대체되는 저장공간이 미리 마련되어있습니다. 

그 저장공간을 범용 레지스터라고 부릅니다. 레지스터는 CPU내에 존재하여 매우 빠르다는 장점이 있습니다.

( 범용 레지스터의 예 : eax, ebx, ecx, edx, ebp, esp, edi, esi, eip 등등.. )

 

mov EAX, 2 // 2를 EAX에 넣는다.
mov EAX, [0x00412345] // 주소 00412345를 EAX에 넣는다.

이 예제를 해석해보면 숫자 2를 EAX라는 레지스터 공간에 넣겠다는 얘기입니다.

두번째 줄은 대괄호[] 안에 있는 주소를 EAX에 넣겠다는 뜻인데, 여기서 대괄호를 쓰게 되면

메모리의 주소를 넣겠다는 얘기가 됩니다. 메모리에는 여러 주소가 존재하고 그 주소를 EAX에 넣어준다는 얘긴거죠.

이 행위를 담당하는 아이는 mov입니다. mov를 우리는 명령어라고 부릅니다

 

이 어셈블리어를 C언어로 표현하게 되면 아래와 같습니다.

(틀린 코드일수도 있어요...! 정말 저의 이론상으로 표현한 코드입니다..)

int eax = 2; // 이해를 돕기 위해 변수이름을 레지스터 이름으로 선언하였습니다.
int* EAX = &eax; // 두번째 줄을 표현해보았습니다.

이제 MOV명령어와 함께 어셈블리에 숟가락정도를 얹어보았다고 말할 수 있습니다!


 

다시 튜토리얼로 돌아와서, 먼저 100이라는 값을 찾아주겠습니다

Value에 100입력후 New Scan버튼 클릭

63개의 메모리가 검색이 되었습니다. 우리가 찾을 메모리는 하나이기때문에 값을 바꿔주고 다시한번 검색을 하겠습니다.

튜토리얼에 <Change value>버튼을 눌러 값을 바꿔줍니다.

Change value버튼을 누르자 578로 변경됨

578로 값이 변경되었기 때문에 578을 Value에 두고 Next Scan을 해줍시다

Value에 578입력후 Next Scan버튼 클릭

578 입력후 Next Scan을 하였더니 한개의 메모리가 검색되었습니다.

검색된 메모리를 테이블로 가져오겠습니다.

검색된 한개의 메모리 주소를 Table로 가져온 화면

여기서 우리는 <Change value> 버튼을 클릭했을 때, 사용되는 어셈블리 코드를 찾아야 합니다.

어셈블리 코드는 치트엔진의 메모리 뷰(Memory view)에서 찾아볼 수 있는데,

Memory View 버튼을 누르면 뷰어가 켜집니다

메모리 뷰에서 찾기엔 매우 많은 어셈블리 코드들이 있다는 것을 알 수 있습니다 ㅠㅠ....

다행히도, 치트엔진에서는 특정 메모리 주소에 어떤 어셈블리 코드쓰기(Write) 되는지 볼 수 있는 기능이 존재합니다!!

 

메모리주소 우클릭 -> Find out what writes to this address 버튼 클릭

메모리주소 우클릭 -> Find out what writes to this address 버튼 클릭

영어를 직역해서 말 그대로 이 메모리 주소에 어떤 쓰기(Write)가 있는지 알아내는겁니다.

 

버튼을 클릭하면 아래와 같은 사진의 이 하나 뜰겁니다

Find out what writes to this address를 클릭하면 나오는 화면(창)

여기서 튜토리얼의 <Change value> 버튼을 클릭해줍니다.

Change value 버튼을 클릭하면 이렇게 하나의 Write가 된 어셈블리코드가 뜹니다.

버튼을 클릭하면 위와같이 어떤 어셈블리 코드가 이 메모리 주소에 쓰기 된건지 볼 수 있습니다.

이 메모리를 클릭하고 <Show disassembler> 버튼을 클릭합니다

오른쪽에 Show disassembler 버튼 클릭해주세요!

그럼 아래와같이 메모리 뷰어가 켜지고 해당 어셈블리 코드의 위치(주소)로 이동하게 됩니다.

메모리 뷰어 화면

위에서 볼 수 있듯이 mov [rax], edx 라는 어셈블리 코드가 사용되었습니다.

정확하게 이게 뭔진 몰라도 우리는 Change value를 눌러서 저 어셈블리 코드가 실행된것이기 때문에

[rax]는 value의 값의 주소를 나타내고, edx는 [rax]에 집어넣을 랜덤한 값을 표시한다는것을 알 수 있습니다!

 

자세하게 다시 설명하면, [rax]는 주소를 나타내고 그 주소에 edx라는 값을 집어넣는 행위가 되겠고,

이 행위는 우리가 change value를 눌렀을때 나타난 어셈블리 코드이기 때문에

바로 위에서 말했듯이, [rax]는 value의 값의 주소를 나타내고, edx는 [rax]에 집어넣을 랜덤한 값을 표시를 합니다.

 

우리는 이 주소를 nop이라는 명령어로 바꿔줄겁니다.

nop은 아무 코드가 없다는 뜻입니다. 특별한 의미가 아니라 아무 명령도 수행하지 않겠다는 명령어입니다.

위와같이 우클릭 -> Assemble를 클릭합니다.

우클릭 -> Assemble 클릭하면 나오는 화면(창)

값을 nop로 바꾸어주고 OK를 클릭합니다.

이상한 경고문이 표시되는데 YES를 클릭합니다.

 

이후 튜토리얼의 Change value 버튼을 눌러주면 값은 안 바뀌게 되므로 NEXT버튼이 활성화됩니다!!

NEXT버튼이 활성화되었습니다!!!

 

 

해킹 강의 : https://studycodes.tistory.com/16

댓글